/*! *****************************************************************************
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.
***************************************************************************** */

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    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
    (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["RegularExpressionLiteral"] = 10] = "RegularExpressionLiteral";
        SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 11] = "NoSubstitutionTemplateLiteral";
        // Pseudo-literals
        SyntaxKind[SyntaxKind["TemplateHead"] = 12] = "TemplateHead";
        SyntaxKind[SyntaxKind["TemplateMiddle"] = 13] = "TemplateMiddle";
        SyntaxKind[SyntaxKind["TemplateTail"] = 14] = "TemplateTail";
        // Punctuation
        SyntaxKind[SyntaxKind["OpenBraceToken"] = 15] = "OpenBraceToken";
        SyntaxKind[SyntaxKind["CloseBraceToken"] = 16] = "CloseBraceToken";
        SyntaxKind[SyntaxKind["OpenParenToken"] = 17] = "OpenParenToken";
        SyntaxKind[SyntaxKind["CloseParenToken"] = 18] = "CloseParenToken";
        SyntaxKind[SyntaxKind["OpenBracketToken"] = 19] = "OpenBracketToken";
        SyntaxKind[SyntaxKind["CloseBracketToken"] = 20] = "CloseBracketToken";
        SyntaxKind[SyntaxKind["DotToken"] = 21] = "DotToken";
        SyntaxKind[SyntaxKind["DotDotDotToken"] = 22] = "DotDotDotToken";
        SyntaxKind[SyntaxKind["SemicolonToken"] = 23] = "SemicolonToken";
        SyntaxKind[SyntaxKind["CommaToken"] = 24] = "CommaToken";
        SyntaxKind[SyntaxKind["LessThanToken"] = 25] = "LessThanToken";
        SyntaxKind[SyntaxKind["LessThanSlashToken"] = 26] = "LessThanSlashToken";
        SyntaxKind[SyntaxKind["GreaterThanToken"] = 27] = "GreaterThanToken";
        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 28] = "LessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 29] = "GreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 30] = "EqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 31] = "ExclamationEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 32] = "EqualsEqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 33] = "ExclamationEqualsEqualsToken";
        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 34] = "EqualsGreaterThanToken";
        SyntaxKind[SyntaxKind["PlusToken"] = 35] = "PlusToken";
        SyntaxKind[SyntaxKind["MinusToken"] = 36] = "MinusToken";
        SyntaxKind[SyntaxKind["AsteriskToken"] = 37] = "AsteriskToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 38] = "AsteriskAsteriskToken";
        SyntaxKind[SyntaxKind["SlashToken"] = 39] = "SlashToken";
        SyntaxKind[SyntaxKind["PercentToken"] = 40] = "PercentToken";
        SyntaxKind[SyntaxKind["PlusPlusToken"] = 41] = "PlusPlusToken";
        SyntaxKind[SyntaxKind["MinusMinusToken"] = 42] = "MinusMinusToken";
        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 43] = "LessThanLessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 44] = "GreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 45] = "GreaterThanGreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["AmpersandToken"] = 46] = "AmpersandToken";
        SyntaxKind[SyntaxKind["BarToken"] = 47] = "BarToken";
        SyntaxKind[SyntaxKind["CaretToken"] = 48] = "CaretToken";
        SyntaxKind[SyntaxKind["ExclamationToken"] = 49] = "ExclamationToken";
        SyntaxKind[SyntaxKind["TildeToken"] = 50] = "TildeToken";
        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 51] = "AmpersandAmpersandToken";
        SyntaxKind[SyntaxKind["BarBarToken"] = 52] = "BarBarToken";
        SyntaxKind[SyntaxKind["QuestionToken"] = 53] = "QuestionToken";
        SyntaxKind[SyntaxKind["ColonToken"] = 54] = "ColonToken";
        SyntaxKind[SyntaxKind["AtToken"] = 55] = "AtToken";
        // Assignments
        SyntaxKind[SyntaxKind["EqualsToken"] = 56] = "EqualsToken";
        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 57] = "PlusEqualsToken";
        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 58] = "MinusEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 59] = "AsteriskEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 60] = "AsteriskAsteriskEqualsToken";
        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 61] = "SlashEqualsToken";
        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 62] = "PercentEqualsToken";
        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 63] = "LessThanLessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 64] = "GreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 65] = "GreaterThanGreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 66] = "AmpersandEqualsToken";
        SyntaxKind[SyntaxKind["BarEqualsToken"] = 67] = "BarEqualsToken";
        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 68] = "CaretEqualsToken";
        // Identifiers
        SyntaxKind[SyntaxKind["Identifier"] = 69] = "Identifier";
        // Reserved words
        SyntaxKind[SyntaxKind["BreakKeyword"] = 70] = "BreakKeyword";
        SyntaxKind[SyntaxKind["CaseKeyword"] = 71] = "CaseKeyword";
        SyntaxKind[SyntaxKind["CatchKeyword"] = 72] = "CatchKeyword";
        SyntaxKind[SyntaxKind["ClassKeyword"] = 73] = "ClassKeyword";
        SyntaxKind[SyntaxKind["ConstKeyword"] = 74] = "ConstKeyword";
        SyntaxKind[SyntaxKind["ContinueKeyword"] = 75] = "ContinueKeyword";
        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 76] = "DebuggerKeyword";
        SyntaxKind[SyntaxKind["DefaultKeyword"] = 77] = "DefaultKeyword";
        SyntaxKind[SyntaxKind["DeleteKeyword"] = 78] = "DeleteKeyword";
        SyntaxKind[SyntaxKind["DoKeyword"] = 79] = "DoKeyword";
        SyntaxKind[SyntaxKind["ElseKeyword"] = 80] = "ElseKeyword";
        SyntaxKind[SyntaxKind["EnumKeyword"] = 81] = "EnumKeyword";
        SyntaxKind[SyntaxKind["ExportKeyword"] = 82] = "ExportKeyword";
        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 83] = "ExtendsKeyword";
        SyntaxKind[SyntaxKind["FalseKeyword"] = 84] = "FalseKeyword";
        SyntaxKind[SyntaxKind["FinallyKeyword"] = 85] = "FinallyKeyword";
        SyntaxKind[SyntaxKind["ForKeyword"] = 86] = "ForKeyword";
        SyntaxKind[SyntaxKind["FunctionKeyword"] = 87] = "FunctionKeyword";
        SyntaxKind[SyntaxKind["IfKeyword"] = 88] = "IfKeyword";
        SyntaxKind[SyntaxKind["ImportKeyword"] = 89] = "ImportKeyword";
        SyntaxKind[SyntaxKind["InKeyword"] = 90] = "InKeyword";
        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 91] = "InstanceOfKeyword";
        SyntaxKind[SyntaxKind["NewKeyword"] = 92] = "NewKeyword";
        SyntaxKind[SyntaxKind["NullKeyword"] = 93] = "NullKeyword";
        SyntaxKind[SyntaxKind["ReturnKeyword"] = 94] = "ReturnKeyword";
        SyntaxKind[SyntaxKind["SuperKeyword"] = 95] = "SuperKeyword";
        SyntaxKind[SyntaxKind["SwitchKeyword"] = 96] = "SwitchKeyword";
        SyntaxKind[SyntaxKind["ThisKeyword"] = 97] = "ThisKeyword";
        SyntaxKind[SyntaxKind["ThrowKeyword"] = 98] = "ThrowKeyword";
        SyntaxKind[SyntaxKind["TrueKeyword"] = 99] = "TrueKeyword";
        SyntaxKind[SyntaxKind["TryKeyword"] = 100] = "TryKeyword";
        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 101] = "TypeOfKeyword";
        SyntaxKind[SyntaxKind["VarKeyword"] = 102] = "VarKeyword";
        SyntaxKind[SyntaxKind["VoidKeyword"] = 103] = "VoidKeyword";
        SyntaxKind[SyntaxKind["WhileKeyword"] = 104] = "WhileKeyword";
        SyntaxKind[SyntaxKind["WithKeyword"] = 105] = "WithKeyword";
        // Strict mode reserved words
        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 106] = "ImplementsKeyword";
        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 107] = "InterfaceKeyword";
        SyntaxKind[SyntaxKind["LetKeyword"] = 108] = "LetKeyword";
        SyntaxKind[SyntaxKind["PackageKeyword"] = 109] = "PackageKeyword";
        SyntaxKind[SyntaxKind["PrivateKeyword"] = 110] = "PrivateKeyword";
        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 111] = "ProtectedKeyword";
        SyntaxKind[SyntaxKind["PublicKeyword"] = 112] = "PublicKeyword";
        SyntaxKind[SyntaxKind["StaticKeyword"] = 113] = "StaticKeyword";
        SyntaxKind[SyntaxKind["YieldKeyword"] = 114] = "YieldKeyword";
        // Contextual keywords
        SyntaxKind[SyntaxKind["AbstractKeyword"] = 115] = "AbstractKeyword";
        SyntaxKind[SyntaxKind["AsKeyword"] = 116] = "AsKeyword";
        SyntaxKind[SyntaxKind["AnyKeyword"] = 117] = "AnyKeyword";
        SyntaxKind[SyntaxKind["AsyncKeyword"] = 118] = "AsyncKeyword";
        SyntaxKind[SyntaxKind["AwaitKeyword"] = 119] = "AwaitKeyword";
        SyntaxKind[SyntaxKind["BooleanKeyword"] = 120] = "BooleanKeyword";
        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 121] = "ConstructorKeyword";
        SyntaxKind[SyntaxKind["DeclareKeyword"] = 122] = "DeclareKeyword";
        SyntaxKind[SyntaxKind["GetKeyword"] = 123] = "GetKeyword";
        SyntaxKind[SyntaxKind["IsKeyword"] = 124] = "IsKeyword";
        SyntaxKind[SyntaxKind["ModuleKeyword"] = 125] = "ModuleKeyword";
        SyntaxKind[SyntaxKind["NamespaceKeyword"] = 126] = "NamespaceKeyword";
        SyntaxKind[SyntaxKind["NeverKeyword"] = 127] = "NeverKeyword";
        SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 128] = "ReadonlyKeyword";
        SyntaxKind[SyntaxKind["RequireKeyword"] = 129] = "RequireKeyword";
        SyntaxKind[SyntaxKind["NumberKeyword"] = 130] = "NumberKeyword";
        SyntaxKind[SyntaxKind["SetKeyword"] = 131] = "SetKeyword";
        SyntaxKind[SyntaxKind["StringKeyword"] = 132] = "StringKeyword";
        SyntaxKind[SyntaxKind["SymbolKeyword"] = 133] = "SymbolKeyword";
        SyntaxKind[SyntaxKind["TypeKeyword"] = 134] = "TypeKeyword";
        SyntaxKind[SyntaxKind["UndefinedKeyword"] = 135] = "UndefinedKeyword";
        SyntaxKind[SyntaxKind["FromKeyword"] = 136] = "FromKeyword";
        SyntaxKind[SyntaxKind["GlobalKeyword"] = 137] = "GlobalKeyword";
        SyntaxKind[SyntaxKind["OfKeyword"] = 138] = "OfKeyword";
        // Parse tree nodes
        // Names
        SyntaxKind[SyntaxKind["QualifiedName"] = 139] = "QualifiedName";
        SyntaxKind[SyntaxKind["ComputedPropertyName"] = 140] = "ComputedPropertyName";
        // Signature elements
        SyntaxKind[SyntaxKind["TypeParameter"] = 141] = "TypeParameter";
        SyntaxKind[SyntaxKind["Parameter"] = 142] = "Parameter";
        SyntaxKind[SyntaxKind["Decorator"] = 143] = "Decorator";
        // TypeMember
        SyntaxKind[SyntaxKind["PropertySignature"] = 144] = "PropertySignature";
        SyntaxKind[SyntaxKind["PropertyDeclaration"] = 145] = "PropertyDeclaration";
        SyntaxKind[SyntaxKind["MethodSignature"] = 146] = "MethodSignature";
        SyntaxKind[SyntaxKind["MethodDeclaration"] = 147] = "MethodDeclaration";
        SyntaxKind[SyntaxKind["Constructor"] = 148] = "Constructor";
        SyntaxKind[SyntaxKind["GetAccessor"] = 149] = "GetAccessor";
        SyntaxKind[SyntaxKind["SetAccessor"] = 150] = "SetAccessor";
        SyntaxKind[SyntaxKind["CallSignature"] = 151] = "CallSignature";
        SyntaxKind[SyntaxKind["ConstructSignature"] = 152] = "ConstructSignature";
        SyntaxKind[SyntaxKind["IndexSignature"] = 153] = "IndexSignature";
        // Type
        SyntaxKind[SyntaxKind["TypePredicate"] = 154] = "TypePredicate";
        SyntaxKind[SyntaxKind["TypeReference"] = 155] = "TypeReference";
        SyntaxKind[SyntaxKind["FunctionType"] = 156] = "FunctionType";
        SyntaxKind[SyntaxKind["ConstructorType"] = 157] = "ConstructorType";
        SyntaxKind[SyntaxKind["TypeQuery"] = 158] = "TypeQuery";
        SyntaxKind[SyntaxKind["TypeLiteral"] = 159] = "TypeLiteral";
        SyntaxKind[SyntaxKind["ArrayType"] = 160] = "ArrayType";
        SyntaxKind[SyntaxKind["TupleType"] = 161] = "TupleType";
        SyntaxKind[SyntaxKind["UnionType"] = 162] = "UnionType";
        SyntaxKind[SyntaxKind["IntersectionType"] = 163] = "IntersectionType";
        SyntaxKind[SyntaxKind["ParenthesizedType"] = 164] = "ParenthesizedType";
        SyntaxKind[SyntaxKind["ThisType"] = 165] = "ThisType";
        SyntaxKind[SyntaxKind["StringLiteralType"] = 166] = "StringLiteralType";
        // Binding patterns
        SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 167] = "ObjectBindingPattern";
        SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 168] = "ArrayBindingPattern";
        SyntaxKind[SyntaxKind["BindingElement"] = 169] = "BindingElement";
        // Expression
        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 170] = "ArrayLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 171] = "ObjectLiteralExpression";
        SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 172] = "PropertyAccessExpression";
        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 173] = "ElementAccessExpression";
        SyntaxKind[SyntaxKind["CallExpression"] = 174] = "CallExpression";
        SyntaxKind[SyntaxKind["NewExpression"] = 175] = "NewExpression";
        SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 176] = "TaggedTemplateExpression";
        SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 177] = "TypeAssertionExpression";
        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 178] = "ParenthesizedExpression";
        SyntaxKind[SyntaxKind["FunctionExpression"] = 179] = "FunctionExpression";
        SyntaxKind[SyntaxKind["ArrowFunction"] = 180] = "ArrowFunction";
        SyntaxKind[SyntaxKind["DeleteExpression"] = 181] = "DeleteExpression";
        SyntaxKind[SyntaxKind["TypeOfExpression"] = 182] = "TypeOfExpression";
        SyntaxKind[SyntaxKind["VoidExpression"] = 183] = "VoidExpression";
        SyntaxKind[SyntaxKind["AwaitExpression"] = 184] = "AwaitExpression";
        SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 185] = "PrefixUnaryExpression";
        SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 186] = "PostfixUnaryExpression";
        SyntaxKind[SyntaxKind["BinaryExpression"] = 187] = "BinaryExpression";
        SyntaxKind[SyntaxKind["ConditionalExpression"] = 188] = "ConditionalExpression";
        SyntaxKind[SyntaxKind["TemplateExpression"] = 189] = "TemplateExpression";
        SyntaxKind[SyntaxKind["YieldExpression"] = 190] = "YieldExpression";
        SyntaxKind[SyntaxKind["SpreadElementExpression"] = 191] = "SpreadElementExpression";
        SyntaxKind[SyntaxKind["ClassExpression"] = 192] = "ClassExpression";
        SyntaxKind[SyntaxKind["OmittedExpression"] = 193] = "OmittedExpression";
        SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 194] = "ExpressionWithTypeArguments";
        SyntaxKind[SyntaxKind["AsExpression"] = 195] = "AsExpression";
        SyntaxKind[SyntaxKind["NonNullExpression"] = 196] = "NonNullExpression";
        // Misc
        SyntaxKind[SyntaxKind["TemplateSpan"] = 197] = "TemplateSpan";
        SyntaxKind[SyntaxKind["SemicolonClassElement"] = 198] = "SemicolonClassElement";
        // Element
        SyntaxKind[SyntaxKind["Block"] = 199] = "Block";
        SyntaxKind[SyntaxKind["VariableStatement"] = 200] = "VariableStatement";
        SyntaxKind[SyntaxKind["EmptyStatement"] = 201] = "EmptyStatement";
        SyntaxKind[SyntaxKind["ExpressionStatement"] = 202] = "ExpressionStatement";
        SyntaxKind[SyntaxKind["IfStatement"] = 203] = "IfStatement";
        SyntaxKind[SyntaxKind["DoStatement"] = 204] = "DoStatement";
        SyntaxKind[SyntaxKind["WhileStatement"] = 205] = "WhileStatement";
        SyntaxKind[SyntaxKind["ForStatement"] = 206] = "ForStatement";
        SyntaxKind[SyntaxKind["ForInStatement"] = 207] = "ForInStatement";
        SyntaxKind[SyntaxKind["ForOfStatement"] = 208] = "ForOfStatement";
        SyntaxKind[SyntaxKind["ContinueStatement"] = 209] = "ContinueStatement";
        SyntaxKind[SyntaxKind["BreakStatement"] = 210] = "BreakStatement";
        SyntaxKind[SyntaxKind["ReturnStatement"] = 211] = "ReturnStatement";
        SyntaxKind[SyntaxKind["WithStatement"] = 212] = "WithStatement";
        SyntaxKind[SyntaxKind["SwitchStatement"] = 213] = "SwitchStatement";
        SyntaxKind[SyntaxKind["LabeledStatement"] = 214] = "LabeledStatement";
        SyntaxKind[SyntaxKind["ThrowStatement"] = 215] = "ThrowStatement";
        SyntaxKind[SyntaxKind["TryStatement"] = 216] = "TryStatement";
        SyntaxKind[SyntaxKind["DebuggerStatement"] = 217] = "DebuggerStatement";
        SyntaxKind[SyntaxKind["VariableDeclaration"] = 218] = "VariableDeclaration";
        SyntaxKind[SyntaxKind["VariableDeclarationList"] = 219] = "VariableDeclarationList";
        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 220] = "FunctionDeclaration";
        SyntaxKind[SyntaxKind["ClassDeclaration"] = 221] = "ClassDeclaration";
        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 222] = "InterfaceDeclaration";
        SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 223] = "TypeAliasDeclaration";
        SyntaxKind[SyntaxKind["EnumDeclaration"] = 224] = "EnumDeclaration";
        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 225] = "ModuleDeclaration";
        SyntaxKind[SyntaxKind["ModuleBlock"] = 226] = "ModuleBlock";
        SyntaxKind[SyntaxKind["CaseBlock"] = 227] = "CaseBlock";
        SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 228] = "NamespaceExportDeclaration";
        SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 229] = "ImportEqualsDeclaration";
        SyntaxKind[SyntaxKind["ImportDeclaration"] = 230] = "ImportDeclaration";
        SyntaxKind[SyntaxKind["ImportClause"] = 231] = "ImportClause";
        SyntaxKind[SyntaxKind["NamespaceImport"] = 232] = "NamespaceImport";
        SyntaxKind[SyntaxKind["NamedImports"] = 233] = "NamedImports";
        SyntaxKind[SyntaxKind["ImportSpecifier"] = 234] = "ImportSpecifier";
        SyntaxKind[SyntaxKind["ExportAssignment"] = 235] = "ExportAssignment";
        SyntaxKind[SyntaxKind["ExportDeclaration"] = 236] = "ExportDeclaration";
        SyntaxKind[SyntaxKind["NamedExports"] = 237] = "NamedExports";
        SyntaxKind[SyntaxKind["ExportSpecifier"] = 238] = "ExportSpecifier";
        SyntaxKind[SyntaxKind["MissingDeclaration"] = 239] = "MissingDeclaration";
        // Module references
        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 240] = "ExternalModuleReference";
        // JSX
        SyntaxKind[SyntaxKind["JsxElement"] = 241] = "JsxElement";
        SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 242] = "JsxSelfClosingElement";
        SyntaxKind[SyntaxKind["JsxOpeningElement"] = 243] = "JsxOpeningElement";
        SyntaxKind[SyntaxKind["JsxText"] = 244] = "JsxText";
        SyntaxKind[SyntaxKind["JsxClosingElement"] = 245] = "JsxClosingElement";
        SyntaxKind[SyntaxKind["JsxAttribute"] = 246] = "JsxAttribute";
        SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 247] = "JsxSpreadAttribute";
        SyntaxKind[SyntaxKind["JsxExpression"] = 248] = "JsxExpression";
        // Clauses
        SyntaxKind[SyntaxKind["CaseClause"] = 249] = "CaseClause";
        SyntaxKind[SyntaxKind["DefaultClause"] = 250] = "DefaultClause";
        SyntaxKind[SyntaxKind["HeritageClause"] = 251] = "HeritageClause";
        SyntaxKind[SyntaxKind["CatchClause"] = 252] = "CatchClause";
        // Property assignments
        SyntaxKind[SyntaxKind["PropertyAssignment"] = 253] = "PropertyAssignment";
        SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 254] = "ShorthandPropertyAssignment";
        // Enum
        SyntaxKind[SyntaxKind["EnumMember"] = 255] = "EnumMember";
        // Top-level nodes
        SyntaxKind[SyntaxKind["SourceFile"] = 256] = "SourceFile";
        // JSDoc nodes
        SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 257] = "JSDocTypeExpression";
        // The * type
        SyntaxKind[SyntaxKind["JSDocAllType"] = 258] = "JSDocAllType";
        // The ? type
        SyntaxKind[SyntaxKind["JSDocUnknownType"] = 259] = "JSDocUnknownType";
        SyntaxKind[SyntaxKind["JSDocArrayType"] = 260] = "JSDocArrayType";
        SyntaxKind[SyntaxKind["JSDocUnionType"] = 261] = "JSDocUnionType";
        SyntaxKind[SyntaxKind["JSDocTupleType"] = 262] = "JSDocTupleType";
        SyntaxKind[SyntaxKind["JSDocNullableType"] = 263] = "JSDocNullableType";
        SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 264] = "JSDocNonNullableType";
        SyntaxKind[SyntaxKind["JSDocRecordType"] = 265] = "JSDocRecordType";
        SyntaxKind[SyntaxKind["JSDocRecordMember"] = 266] = "JSDocRecordMember";
        SyntaxKind[SyntaxKind["JSDocTypeReference"] = 267] = "JSDocTypeReference";
        SyntaxKind[SyntaxKind["JSDocOptionalType"] = 268] = "JSDocOptionalType";
        SyntaxKind[SyntaxKind["JSDocFunctionType"] = 269] = "JSDocFunctionType";
        SyntaxKind[SyntaxKind["JSDocVariadicType"] = 270] = "JSDocVariadicType";
        SyntaxKind[SyntaxKind["JSDocConstructorType"] = 271] = "JSDocConstructorType";
        SyntaxKind[SyntaxKind["JSDocThisType"] = 272] = "JSDocThisType";
        SyntaxKind[SyntaxKind["JSDocComment"] = 273] = "JSDocComment";
        SyntaxKind[SyntaxKind["JSDocTag"] = 274] = "JSDocTag";
        SyntaxKind[SyntaxKind["JSDocParameterTag"] = 275] = "JSDocParameterTag";
        SyntaxKind[SyntaxKind["JSDocReturnTag"] = 276] = "JSDocReturnTag";
        SyntaxKind[SyntaxKind["JSDocTypeTag"] = 277] = "JSDocTypeTag";
        SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 278] = "JSDocTemplateTag";
        SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 279] = "JSDocTypedefTag";
        SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 280] = "JSDocPropertyTag";
        SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 281] = "JSDocTypeLiteral";
        // Synthesized list
        SyntaxKind[SyntaxKind["SyntaxList"] = 282] = "SyntaxList";
        // Enum value count
        SyntaxKind[SyntaxKind["Count"] = 283] = "Count";
        // Markers
        SyntaxKind[SyntaxKind["FirstAssignment"] = 56] = "FirstAssignment";
        SyntaxKind[SyntaxKind["LastAssignment"] = 68] = "LastAssignment";
        SyntaxKind[SyntaxKind["FirstReservedWord"] = 70] = "FirstReservedWord";
        SyntaxKind[SyntaxKind["LastReservedWord"] = 105] = "LastReservedWord";
        SyntaxKind[SyntaxKind["FirstKeyword"] = 70] = "FirstKeyword";
        SyntaxKind[SyntaxKind["LastKeyword"] = 138] = "LastKeyword";
        SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 106] = "FirstFutureReservedWord";
        SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 114] = "LastFutureReservedWord";
        SyntaxKind[SyntaxKind["FirstTypeNode"] = 154] = "FirstTypeNode";
        SyntaxKind[SyntaxKind["LastTypeNode"] = 166] = "LastTypeNode";
        SyntaxKind[SyntaxKind["FirstPunctuation"] = 15] = "FirstPunctuation";
        SyntaxKind[SyntaxKind["LastPunctuation"] = 68] = "LastPunctuation";
        SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
        SyntaxKind[SyntaxKind["LastToken"] = 138] = "LastToken";
        SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
        SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken";
        SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
        SyntaxKind[SyntaxKind["LastLiteralToken"] = 11] = "LastLiteralToken";
        SyntaxKind[SyntaxKind["FirstTemplateToken"] = 11] = "FirstTemplateToken";
        SyntaxKind[SyntaxKind["LastTemplateToken"] = 14] = "LastTemplateToken";
        SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 25] = "FirstBinaryOperator";
        SyntaxKind[SyntaxKind["LastBinaryOperator"] = 68] = "LastBinaryOperator";
        SyntaxKind[SyntaxKind["FirstNode"] = 139] = "FirstNode";
        SyntaxKind[SyntaxKind["FirstJSDocNode"] = 257] = "FirstJSDocNode";
        SyntaxKind[SyntaxKind["LastJSDocNode"] = 281] = "LastJSDocNode";
        SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 273] = "FirstJSDocTagNode";
        SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 281] = "LastJSDocTagNode";
    })(ts.SyntaxKind || (ts.SyntaxKind = {}));
    var SyntaxKind = ts.SyntaxKind;
    (function (NodeFlags) {
        NodeFlags[NodeFlags["None"] = 0] = "None";
        NodeFlags[NodeFlags["Export"] = 1] = "Export";
        NodeFlags[NodeFlags["Ambient"] = 2] = "Ambient";
        NodeFlags[NodeFlags["Public"] = 4] = "Public";
        NodeFlags[NodeFlags["Private"] = 8] = "Private";
        NodeFlags[NodeFlags["Protected"] = 16] = "Protected";
        NodeFlags[NodeFlags["Static"] = 32] = "Static";
        NodeFlags[NodeFlags["Readonly"] = 64] = "Readonly";
        NodeFlags[NodeFlags["Abstract"] = 128] = "Abstract";
        NodeFlags[NodeFlags["Async"] = 256] = "Async";
        NodeFlags[NodeFlags["Default"] = 512] = "Default";
        NodeFlags[NodeFlags["Let"] = 1024] = "Let";
        NodeFlags[NodeFlags["Const"] = 2048] = "Const";
        NodeFlags[NodeFlags["Namespace"] = 4096] = "Namespace";
        NodeFlags[NodeFlags["ExportContext"] = 8192] = "ExportContext";
        NodeFlags[NodeFlags["ContainsThis"] = 16384] = "ContainsThis";
        NodeFlags[NodeFlags["HasImplicitReturn"] = 32768] = "HasImplicitReturn";
        NodeFlags[NodeFlags["HasExplicitReturn"] = 65536] = "HasExplicitReturn";
        NodeFlags[NodeFlags["GlobalAugmentation"] = 131072] = "GlobalAugmentation";
        NodeFlags[NodeFlags["HasClassExtends"] = 262144] = "HasClassExtends";
        NodeFlags[NodeFlags["HasDecorators"] = 524288] = "HasDecorators";
        NodeFlags[NodeFlags["HasParamDecorators"] = 1048576] = "HasParamDecorators";
        NodeFlags[NodeFlags["HasAsyncFunctions"] = 2097152] = "HasAsyncFunctions";
        NodeFlags[NodeFlags["DisallowInContext"] = 4194304] = "DisallowInContext";
        NodeFlags[NodeFlags["YieldContext"] = 8388608] = "YieldContext";
        NodeFlags[NodeFlags["DecoratorContext"] = 16777216] = "DecoratorContext";
        NodeFlags[NodeFlags["AwaitContext"] = 33554432] = "AwaitContext";
        NodeFlags[NodeFlags["ThisNodeHasError"] = 67108864] = "ThisNodeHasError";
        NodeFlags[NodeFlags["JavaScriptFile"] = 134217728] = "JavaScriptFile";
        NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 268435456] = "ThisNodeOrAnySubNodesHasError";
        NodeFlags[NodeFlags["HasAggregatedChildData"] = 536870912] = "HasAggregatedChildData";
        NodeFlags[NodeFlags["HasJsxSpreadAttribute"] = 1073741824] = "HasJsxSpreadAttribute";
        NodeFlags[NodeFlags["Modifier"] = 1023] = "Modifier";
        NodeFlags[NodeFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier";
        // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
        NodeFlags[NodeFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier";
        NodeFlags[NodeFlags["BlockScoped"] = 3072] = "BlockScoped";
        NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 98304] = "ReachabilityCheckFlags";
        NodeFlags[NodeFlags["EmitHelperFlags"] = 3932160] = "EmitHelperFlags";
        NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 4030464] = "ReachabilityAndEmitFlags";
        // Parsing context flags
        NodeFlags[NodeFlags["ContextFlags"] = 197132288] = "ContextFlags";
        // Exclude these flags when parsing a Type
        NodeFlags[NodeFlags["TypeExcludesFlags"] = 41943040] = "TypeExcludesFlags";
    })(ts.NodeFlags || (ts.NodeFlags = {}));
    var NodeFlags = ts.NodeFlags;
    (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";
    })(ts.JsxFlags || (ts.JsxFlags = {}));
    var JsxFlags = ts.JsxFlags;
    /* @internal */
    (function (RelationComparisonResult) {
        RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded";
        RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed";
        RelationComparisonResult[RelationComparisonResult["FailedAndReported"] = 3] = "FailedAndReported";
    })(ts.RelationComparisonResult || (ts.RelationComparisonResult = {}));
    var RelationComparisonResult = ts.RelationComparisonResult;
    (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["Referenced"] = 256] = "Referenced";
        FlowFlags[FlowFlags["Shared"] = 512] = "Shared";
        FlowFlags[FlowFlags["Label"] = 12] = "Label";
        FlowFlags[FlowFlags["Condition"] = 96] = "Condition";
    })(ts.FlowFlags || (ts.FlowFlags = {}));
    var FlowFlags = ts.FlowFlags;
    var OperationCanceledException = (function () {
        function OperationCanceledException() {
        }
        return OperationCanceledException;
    }());
    ts.OperationCanceledException = OperationCanceledException;
    /** Return code used by getEmitOutput function to indicate status of the function */
    (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";
    })(ts.ExitStatus || (ts.ExitStatus = {}));
    var ExitStatus = ts.ExitStatus;
    (function (TypeFormatFlags) {
        TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
        TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 1] = "WriteArrayAsGenericType";
        TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 2] = "UseTypeOfFunction";
        TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 4] = "NoTruncation";
        TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 8] = "WriteArrowStyleSignature";
        TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 16] = "WriteOwnNameForAnyLike";
        TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        TypeFormatFlags[TypeFormatFlags["InElementType"] = 64] = "InElementType";
        TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 128] = "UseFullyQualifiedType";
        TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 256] = "InFirstTypeArgument";
    })(ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
    var TypeFormatFlags = ts.TypeFormatFlags;
    (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";
    })(ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
    var SymbolFormatFlags = ts.SymbolFormatFlags;
    /* @internal */
    (function (SymbolAccessibility) {
        SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
        SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
        SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
    })(ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
    var SymbolAccessibility = ts.SymbolAccessibility;
    (function (TypePredicateKind) {
        TypePredicateKind[TypePredicateKind["This"] = 0] = "This";
        TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier";
    })(ts.TypePredicateKind || (ts.TypePredicateKind = {}));
    var TypePredicateKind = ts.TypePredicateKind;
    /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator
      * metadata */
    /* @internal */
    (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["VoidType"] = 2] = "VoidType";
        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["TypeWithCallSignature"] = 8] = "TypeWithCallSignature";
        // with call signatures.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 9] = "ObjectType";
    })(ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {}));
    var TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind;
    (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["ExportType"] = 2097152] = "ExportType";
        SymbolFlags[SymbolFlags["ExportNamespace"] = 4194304] = "ExportNamespace";
        SymbolFlags[SymbolFlags["Alias"] = 8388608] = "Alias";
        SymbolFlags[SymbolFlags["Instantiated"] = 16777216] = "Instantiated";
        SymbolFlags[SymbolFlags["Merged"] = 33554432] = "Merged";
        SymbolFlags[SymbolFlags["Transient"] = 67108864] = "Transient";
        SymbolFlags[SymbolFlags["Prototype"] = 134217728] = "Prototype";
        SymbolFlags[SymbolFlags["SyntheticProperty"] = 268435456] = "SyntheticProperty";
        SymbolFlags[SymbolFlags["Optional"] = 536870912] = "Optional";
        SymbolFlags[SymbolFlags["ExportStar"] = 1073741824] = "ExportStar";
        SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
        SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
        SymbolFlags[SymbolFlags["Value"] = 107455] = "Value";
        SymbolFlags[SymbolFlags["Type"] = 793056] = "Type";
        SymbolFlags[SymbolFlags["Namespace"] = 1536] = "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"] = 107455] = "EnumMemberExcludes";
        SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes";
        SymbolFlags[SymbolFlags["ClassExcludes"] = 899519] = "ClassExcludes";
        SymbolFlags[SymbolFlags["InterfaceExcludes"] = 792960] = "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"] = 530912] = "TypeParameterExcludes";
        SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 793056] = "TypeAliasExcludes";
        SymbolFlags[SymbolFlags["AliasExcludes"] = 8388608] = "AliasExcludes";
        SymbolFlags[SymbolFlags["ModuleMember"] = 8914931] = "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["Export"] = 7340032] = "Export";
        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";
    })(ts.SymbolFlags || (ts.SymbolFlags = {}));
    var SymbolFlags = ts.SymbolFlags;
    /* @internal */
    (function (NodeCheckFlags) {
        NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
        NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
        NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
        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";
    })(ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
    var NodeCheckFlags = ts.NodeCheckFlags;
    (function (TypeFlags) {
        TypeFlags[TypeFlags["Any"] = 1] = "Any";
        TypeFlags[TypeFlags["String"] = 2] = "String";
        TypeFlags[TypeFlags["Number"] = 4] = "Number";
        TypeFlags[TypeFlags["Boolean"] = 8] = "Boolean";
        TypeFlags[TypeFlags["Void"] = 16] = "Void";
        TypeFlags[TypeFlags["Undefined"] = 32] = "Undefined";
        TypeFlags[TypeFlags["Null"] = 64] = "Null";
        TypeFlags[TypeFlags["Enum"] = 128] = "Enum";
        TypeFlags[TypeFlags["StringLiteral"] = 256] = "StringLiteral";
        TypeFlags[TypeFlags["TypeParameter"] = 512] = "TypeParameter";
        TypeFlags[TypeFlags["Class"] = 1024] = "Class";
        TypeFlags[TypeFlags["Interface"] = 2048] = "Interface";
        TypeFlags[TypeFlags["Reference"] = 4096] = "Reference";
        TypeFlags[TypeFlags["Tuple"] = 8192] = "Tuple";
        TypeFlags[TypeFlags["Union"] = 16384] = "Union";
        TypeFlags[TypeFlags["Intersection"] = 32768] = "Intersection";
        TypeFlags[TypeFlags["Anonymous"] = 65536] = "Anonymous";
        TypeFlags[TypeFlags["Instantiated"] = 131072] = "Instantiated";
        /* @internal */
        TypeFlags[TypeFlags["FromSignature"] = 262144] = "FromSignature";
        TypeFlags[TypeFlags["ObjectLiteral"] = 524288] = "ObjectLiteral";
        /* @internal */
        TypeFlags[TypeFlags["FreshObjectLiteral"] = 1048576] = "FreshObjectLiteral";
        /* @internal */
        TypeFlags[TypeFlags["ContainsWideningType"] = 2097152] = "ContainsWideningType";
        /* @internal */
        TypeFlags[TypeFlags["ContainsObjectLiteral"] = 4194304] = "ContainsObjectLiteral";
        /* @internal */
        TypeFlags[TypeFlags["ContainsAnyFunctionType"] = 8388608] = "ContainsAnyFunctionType";
        TypeFlags[TypeFlags["ESSymbol"] = 16777216] = "ESSymbol";
        TypeFlags[TypeFlags["ThisType"] = 33554432] = "ThisType";
        TypeFlags[TypeFlags["ObjectLiteralPatternWithComputedProperties"] = 67108864] = "ObjectLiteralPatternWithComputedProperties";
        TypeFlags[TypeFlags["Never"] = 134217728] = "Never";
        /* @internal */
        TypeFlags[TypeFlags["Nullable"] = 96] = "Nullable";
        /* @internal */
        TypeFlags[TypeFlags["Falsy"] = 112] = "Falsy";
        /* @internal */
        TypeFlags[TypeFlags["Intrinsic"] = 150995071] = "Intrinsic";
        /* @internal */
        TypeFlags[TypeFlags["Primitive"] = 16777726] = "Primitive";
        TypeFlags[TypeFlags["StringLike"] = 258] = "StringLike";
        TypeFlags[TypeFlags["NumberLike"] = 132] = "NumberLike";
        TypeFlags[TypeFlags["ObjectType"] = 80896] = "ObjectType";
        TypeFlags[TypeFlags["UnionOrIntersection"] = 49152] = "UnionOrIntersection";
        TypeFlags[TypeFlags["StructuredType"] = 130048] = "StructuredType";
        // 'Narrowable' types are types where narrowing actually narrows.
        // This *should* be every type other than null, undefined, void, and never
        TypeFlags[TypeFlags["Narrowable"] = 16908175] = "Narrowable";
        /* @internal */
        TypeFlags[TypeFlags["RequiresWidening"] = 6291456] = "RequiresWidening";
        /* @internal */
        TypeFlags[TypeFlags["PropagatingFlags"] = 14680064] = "PropagatingFlags";
    })(ts.TypeFlags || (ts.TypeFlags = {}));
    var TypeFlags = ts.TypeFlags;
    (function (SignatureKind) {
        SignatureKind[SignatureKind["Call"] = 0] = "Call";
        SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
    })(ts.SignatureKind || (ts.SignatureKind = {}));
    var SignatureKind = ts.SignatureKind;
    (function (IndexKind) {
        IndexKind[IndexKind["String"] = 0] = "String";
        IndexKind[IndexKind["Number"] = 1] = "Number";
    })(ts.IndexKind || (ts.IndexKind = {}));
    var IndexKind = ts.IndexKind;
    /* @internal */
    (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";
    })(ts.SpecialPropertyAssignmentKind || (ts.SpecialPropertyAssignmentKind = {}));
    var SpecialPropertyAssignmentKind = ts.SpecialPropertyAssignmentKind;
    (function (DiagnosticCategory) {
        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
        DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message";
    })(ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
    var DiagnosticCategory = ts.DiagnosticCategory;
    (function (ModuleResolutionKind) {
        ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic";
        ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs";
    })(ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {}));
    var ModuleResolutionKind = ts.ModuleResolutionKind;
    (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["ES6"] = 5] = "ES6";
        ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015";
    })(ts.ModuleKind || (ts.ModuleKind = {}));
    var ModuleKind = ts.ModuleKind;
    (function (JsxEmit) {
        JsxEmit[JsxEmit["None"] = 0] = "None";
        JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve";
        JsxEmit[JsxEmit["React"] = 2] = "React";
    })(ts.JsxEmit || (ts.JsxEmit = {}));
    var JsxEmit = ts.JsxEmit;
    (function (NewLineKind) {
        NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed";
        NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed";
    })(ts.NewLineKind || (ts.NewLineKind = {}));
    var NewLineKind = ts.NewLineKind;
    (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";
    })(ts.ScriptKind || (ts.ScriptKind = {}));
    var ScriptKind = ts.ScriptKind;
    (function (ScriptTarget) {
        ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
        ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
        ScriptTarget[ScriptTarget["ES6"] = 2] = "ES6";
        ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015";
        ScriptTarget[ScriptTarget["Latest"] = 2] = "Latest";
    })(ts.ScriptTarget || (ts.ScriptTarget = {}));
    var ScriptTarget = ts.ScriptTarget;
    (function (LanguageVariant) {
        LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard";
        LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX";
    })(ts.LanguageVariant || (ts.LanguageVariant = {}));
    var LanguageVariant = ts.LanguageVariant;
    /* @internal */
    (function (DiagnosticStyle) {
        DiagnosticStyle[DiagnosticStyle["Simple"] = 0] = "Simple";
        DiagnosticStyle[DiagnosticStyle["Pretty"] = 1] = "Pretty";
    })(ts.DiagnosticStyle || (ts.DiagnosticStyle = {}));
    var DiagnosticStyle = ts.DiagnosticStyle;
    (function (WatchDirectoryFlags) {
        WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None";
        WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive";
    })(ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {}));
    var WatchDirectoryFlags = ts.WatchDirectoryFlags;
    /* @internal */
    (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";
    })(ts.CharacterCodes || (ts.CharacterCodes = {}));
    var CharacterCodes = ts.CharacterCodes;
})(ts || (ts = {}));
/// <reference path="types.ts"/>
/* @internal */
var ts;
(function (ts) {
    /**
     * 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.
     */
    (function (Ternary) {
        Ternary[Ternary["False"] = 0] = "False";
        Ternary[Ternary["Maybe"] = 1] = "Maybe";
        Ternary[Ternary["True"] = -1] = "True";
    })(ts.Ternary || (ts.Ternary = {}));
    var Ternary = ts.Ternary;
    function createFileMap(keyMapper) {
        var files = {};
        return {
            get: get,
            set: set,
            contains: contains,
            remove: remove,
            forEachValue: forEachValueInMap,
            clear: clear
        };
        function forEachValueInMap(f) {
            for (var key in files) {
                f(key, files[key]);
            }
        }
        // path should already be well-formed so it does not need to be normalized
        function get(path) {
            return files[toKey(path)];
        }
        function set(path, value) {
            files[toKey(path)] = value;
        }
        function contains(path) {
            return hasProperty(files, toKey(path));
        }
        function remove(path) {
            var key = toKey(path);
            delete files[key];
        }
        function clear() {
            files = {};
        }
        function toKey(path) {
            return keyMapper ? keyMapper(path) : path;
        }
    }
    ts.createFileMap = createFileMap;
    function toPath(fileName, basePath, getCanonicalFileName) {
        var nonCanonicalizedPath = isRootedDiskPath(fileName)
            ? normalizePath(fileName)
            : getNormalizedAbsolutePath(fileName, basePath);
        return getCanonicalFileName(nonCanonicalizedPath);
    }
    ts.toPath = toPath;
    (function (Comparison) {
        Comparison[Comparison["LessThan"] = -1] = "LessThan";
        Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
        Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
    })(ts.Comparison || (ts.Comparison = {}));
    var Comparison = ts.Comparison;
    /**
     * 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, len = array.length; i < len; i++) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEach = forEach;
    function contains(array, value, areEqual) {
        if (array) {
            for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
                var v = array_1[_i];
                if (areEqual ? areEqual(v, value) : v === value) {
                    return true;
                }
            }
        }
        return false;
    }
    ts.contains = contains;
    function indexOf(array, value) {
        if (array) {
            for (var i = 0, len = array.length; i < len; i++) {
                if (array[i] === value) {
                    return i;
                }
            }
        }
        return -1;
    }
    ts.indexOf = indexOf;
    function indexOfAnyCharCode(text, charCodes, start) {
        for (var i = start || 0, len = text.length; i < len; 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, array_2 = array; _i < array_2.length; _i++) {
                var v = array_2[_i];
                if (predicate(v)) {
                    count++;
                }
            }
        }
        return count;
    }
    ts.countWhere = countWhere;
    function filter(array, f) {
        var result;
        if (array) {
            result = [];
            for (var _i = 0, array_3 = array; _i < array_3.length; _i++) {
                var item = array_3[_i];
                if (f(item)) {
                    result.push(item);
                }
            }
        }
        return result;
    }
    ts.filter = filter;
    function filterMutate(array, f) {
        var outIndex = 0;
        for (var _i = 0, array_4 = array; _i < array_4.length; _i++) {
            var item = array_4[_i];
            if (f(item)) {
                array[outIndex] = item;
                outIndex++;
            }
        }
        array.length = outIndex;
    }
    ts.filterMutate = filterMutate;
    function map(array, f) {
        var result;
        if (array) {
            result = [];
            for (var _i = 0, array_5 = array; _i < array_5.length; _i++) {
                var v = array_5[_i];
                result.push(f(v));
            }
        }
        return result;
    }
    ts.map = map;
    function concatenate(array1, array2) {
        if (!array2 || !array2.length)
            return array1;
        if (!array1 || !array1.length)
            return array2;
        return array1.concat(array2);
    }
    ts.concatenate = concatenate;
    function deduplicate(array, areEqual) {
        var result;
        if (array) {
            result = [];
            for (var _i = 0, array_6 = array; _i < array_6.length; _i++) {
                var item = array_6[_i];
                if (!contains(result, item, areEqual)) {
                    result.push(item);
                }
            }
        }
        return result;
    }
    ts.deduplicate = deduplicate;
    function sum(array, prop) {
        var result = 0;
        for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
            var v = array_7[_i];
            result += v[prop];
        }
        return result;
    }
    ts.sum = sum;
    function addRange(to, from) {
        if (to && from) {
            for (var _i = 0, from_1 = from; _i < from_1.length; _i++) {
                var v = from_1[_i];
                to.push(v);
            }
        }
    }
    ts.addRange = addRange;
    function rangeEquals(array1, array2, pos, end) {
        while (pos < end) {
            if (array1[pos] !== array2[pos]) {
                return false;
            }
            pos++;
        }
        return true;
    }
    ts.rangeEquals = rangeEquals;
    /**
     * Returns the last element of an array if non-empty, undefined otherwise.
     */
    function lastOrUndefined(array) {
        if (array.length === 0) {
            return undefined;
        }
        return array[array.length - 1];
    }
    ts.lastOrUndefined = lastOrUndefined;
    /**
     * 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) {
        var low = 0;
        var high = array.length - 1;
        while (low <= high) {
            var middle = low + ((high - low) >> 1);
            var midValue = array[middle];
            if (midValue === value) {
                return middle;
            }
            else if (midValue > value) {
                high = middle - 1;
            }
            else {
                low = middle + 1;
            }
        }
        return ~low;
    }
    ts.binarySearch = binarySearch;
    function reduceLeft(array, f, initial) {
        if (array) {
            var count = array.length;
            if (count > 0) {
                var pos = 0;
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos++;
                }
                else {
                    result = initial;
                }
                while (pos < count) {
                    result = f(result, array[pos]);
                    pos++;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceLeft = reduceLeft;
    function reduceRight(array, f, initial) {
        if (array) {
            var pos = array.length - 1;
            if (pos >= 0) {
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos--;
                }
                else {
                    result = initial;
                }
                while (pos >= 0) {
                    result = f(result, array[pos]);
                    pos--;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceRight = reduceRight;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    function hasProperty(map, key) {
        return hasOwnProperty.call(map, key);
    }
    ts.hasProperty = hasProperty;
    function getKeys(map) {
        var keys = [];
        for (var key in map) {
            keys.push(key);
        }
        return keys;
    }
    ts.getKeys = getKeys;
    function getProperty(map, key) {
        return hasOwnProperty.call(map, key) ? map[key] : undefined;
    }
    ts.getProperty = getProperty;
    function isEmpty(map) {
        for (var id in map) {
            if (hasProperty(map, id)) {
                return false;
            }
        }
        return true;
    }
    ts.isEmpty = isEmpty;
    function clone(object) {
        var result = {};
        for (var id in object) {
            result[id] = object[id];
        }
        return result;
    }
    ts.clone = clone;
    function extend(first, second) {
        var result = {};
        for (var id in first) {
            result[id] = first[id];
        }
        for (var id in second) {
            if (!hasProperty(result, id)) {
                result[id] = second[id];
            }
        }
        return result;
    }
    ts.extend = extend;
    function forEachValue(map, callback) {
        var result;
        for (var id in map) {
            if (result = callback(map[id]))
                break;
        }
        return result;
    }
    ts.forEachValue = forEachValue;
    function forEachKey(map, callback) {
        var result;
        for (var id in map) {
            if (result = callback(id))
                break;
        }
        return result;
    }
    ts.forEachKey = forEachKey;
    function lookUp(map, key) {
        return hasProperty(map, key) ? map[key] : undefined;
    }
    ts.lookUp = lookUp;
    function copyMap(source, target) {
        for (var p in source) {
            target[p] = source[p];
        }
    }
    ts.copyMap = copyMap;
    /**
     * Creates a map from the elements of an array.
     *
     * @param array the array of input elements.
     * @param makeKey a function that produces a key for a given element.
     *
     * This function makes no effort to avoid collisions; if any two elements produce
     * the same key with the given 'makeKey' function, then the element with the higher
     * index in the array will be the one associated with the produced key.
     */
    function arrayToMap(array, makeKey) {
        var result = {};
        forEach(array, function (value) {
            result[makeKey(value)] = value;
        });
        return result;
    }
    ts.arrayToMap = arrayToMap;
    /**
     * Reduce the properties of a map.
     *
     * @param map The map to reduce
     * @param callback An aggregation function that is called for each entry in the map
     * @param initial The initial value for the reduction.
     */
    function reduceProperties(map, callback, initial) {
        var result = initial;
        if (map) {
            for (var key in map) {
                if (hasProperty(map, key)) {
                    result = callback(result, map[key], String(key));
                }
            }
        }
        return result;
    }
    ts.reduceProperties = reduceProperties;
    /**
     * Tests whether a value is an array.
     */
    function isArray(value) {
        return Array.isArray ? Array.isArray(value) : value instanceof Array;
    }
    ts.isArray = isArray;
    function memoize(callback) {
        var value;
        return function () {
            if (callback) {
                value = callback();
                callback = undefined;
            }
            return value;
        };
    }
    ts.memoize = memoize;
    function formatStringFromArgs(text, args, baseIndex) {
        baseIndex = baseIndex || 0;
        return text.replace(/{(\d+)}/g, function (match, index) { return args[+index + baseIndex]; });
    }
    ts.localizedDiagnosticMessages = undefined;
    function getLocaleSpecificMessage(message) {
        return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key]
            ? ts.localizedDiagnosticMessages[message.key]
            : message.message;
    }
    ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
    function createFileDiagnostic(file, start, length, message) {
        var end = start + length;
        Debug.assert(start >= 0, "start must be non-negative, is " + start);
        Debug.assert(length >= 0, "length must be non-negative, is " + length);
        if (file) {
            Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length);
            Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + 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 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) {
            if (String.prototype.localeCompare) {
                var result = a.localeCompare(b, /*locales*/ undefined, { usage: "sort", sensitivity: "accent" });
                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 = typeof text1 === "string" ? text1 : text1.messageText;
            var string2 = typeof text2 === "string" ? text2 : text2.messageText;
            var res = compareValues(string1, string2);
            if (res) {
                return res;
            }
            text1 = typeof text1 === "string" ? undefined : text1.next;
            text2 = typeof text2 === "string" ? 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;
    ts.directorySeparator = "/";
    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) {
        path = normalizeSlashes(path);
        var rootLength = getRootLength(path);
        var normalized = getNormalizedParts(path, rootLength);
        return path.substr(0, rootLength) + normalized.join(ts.directorySeparator);
    }
    ts.normalizePath = normalizePath;
    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) && path.indexOf("://") !== -1;
    }
    ts.isUrl = isUrl;
    function isRootedDiskPath(path) {
        return getRootLength(path) !== 0;
    }
    ts.isRootedDiskPath = isRootedDiskPath;
    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.length--;
        }
        // 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;
    /**
     * Removes a trailing directory separator from a path.
     * @param path The path.
     */
    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 fileExtensionIs(path, extension) {
        var pathLen = path.length;
        var extLen = extension.length;
        return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension;
    }
    ts.fileExtensionIs = fileExtensionIs;
    function fileExtensionIsAny(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.fileExtensionIsAny = fileExtensionIsAny;
    // 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 */];
    function getRegularExpressionForWildcard(specs, basePath, usage) {
        if (specs === undefined || specs.length === 0) {
            return undefined;
        }
        var pattern = "";
        var hasWrittenSubpattern = false;
        spec: for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) {
            var spec = specs_1[_i];
            if (!spec) {
                continue;
            }
            var subpattern = "";
            var hasRecursiveDirectoryWildcard = false;
            var hasWrittenComponent = false;
            var components = getNormalizedPathComponents(spec, basePath);
            if (usage !== "exclude" && components[components.length - 1] === "**") {
                continue spec;
            }
            // getNormalizedPathComponents includes the separator for the root component.
            // We need to remove to create our regex correctly.
            components[0] = removeTrailingDirectorySeparator(components[0]);
            var optionalCount = 0;
            for (var _a = 0, components_1 = components; _a < components_1.length; _a++) {
                var component = components_1[_a];
                if (component === "**") {
                    if (hasRecursiveDirectoryWildcard) {
                        continue spec;
                    }
                    subpattern += "(/.+?)?";
                    hasRecursiveDirectoryWildcard = true;
                    hasWrittenComponent = true;
                }
                else {
                    if (usage === "directories") {
                        subpattern += "(";
                        optionalCount++;
                    }
                    if (hasWrittenComponent) {
                        subpattern += ts.directorySeparator;
                    }
                    subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                    hasWrittenComponent = true;
                }
            }
            while (optionalCount > 0) {
                subpattern += ")?";
                optionalCount--;
            }
            if (hasWrittenSubpattern) {
                pattern += "|";
            }
            pattern += "(" + subpattern + ")";
            hasWrittenSubpattern = true;
        }
        if (!pattern) {
            return undefined;
        }
        return "^(" + pattern + (usage === "exclude" ? ")($|/)" : ")$");
    }
    ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard;
    function replaceWildcardCharacter(match) {
        return match === "*" ? "[^/]*" : match === "?" ? "[^/]" : "\\" + match;
    }
    function getFileMatcherPatterns(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
        path = normalizePath(path);
        currentDirectory = normalizePath(currentDirectory);
        var absolutePath = combinePaths(currentDirectory, path);
        return {
            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, getFileSystemEntries) {
        path = normalizePath(path);
        currentDirectory = normalizePath(currentDirectory);
        var patterns = getFileMatcherPatterns(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
        var regexFlag = useCaseSensitiveFileNames ? "" : "i";
        var includeFileRegex = patterns.includeFilePattern && new RegExp(patterns.includeFilePattern, regexFlag);
        var includeDirectoryRegex = patterns.includeDirectoryPattern && new RegExp(patterns.includeDirectoryPattern, regexFlag);
        var excludeRegex = patterns.excludePattern && new RegExp(patterns.excludePattern, regexFlag);
        var result = [];
        for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) {
            var basePath = _a[_i];
            visitDirectory(basePath, combinePaths(currentDirectory, basePath));
        }
        return result;
        function visitDirectory(path, absolutePath) {
            var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories;
            for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
                var current = files_1[_i];
                var name_1 = combinePaths(path, current);
                var absoluteName = combinePaths(absolutePath, current);
                if ((!extensions || fileExtensionIsAny(name_1, extensions)) &&
                    (!includeFileRegex || includeFileRegex.test(absoluteName)) &&
                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
                    result.push(name_1);
                }
            }
            for (var _b = 0, directories_1 = directories; _b < directories_1.length; _b++) {
                var current = directories_1[_b];
                var name_2 = combinePaths(path, current);
                var absoluteName = combinePaths(absolutePath, current);
                if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
                    visitDirectory(name_2, absoluteName);
                }
            }
        }
    }
    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));
                var wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
                var includeBasePath = wildcardOffset < 0
                    ? removeTrailingDirectorySeparator(getDirectoryPath(absolute))
                    : absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset));
                // Append the literal and canonical candidate base paths.
                includeBasePaths.push(includeBasePath);
            }
            // Sort the offsets array using either the literal or canonical path representations.
            includeBasePaths.sort(useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive);
            // Iterate over each include base path and include unique base paths that are not a
            // subpath of an existing base path
            include: for (var i = 0; i < includeBasePaths.length; i++) {
                var includeBasePath = includeBasePaths[i];
                for (var j = 0; j < basePaths.length; j++) {
                    if (containsPath(basePaths[j], includeBasePath, path, !useCaseSensitiveFileNames)) {
                        continue include;
                    }
                }
                basePaths.push(includeBasePath);
            }
        }
        return basePaths;
    }
    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":
                return 1 /* JS */;
            case ".jsx":
                return 2 /* JSX */;
            case ".ts":
                return 3 /* TS */;
            case ".tsx":
                return 4 /* TSX */;
            default:
                return 0 /* Unknown */;
        }
    }
    ts.getScriptKindFromFileName = getScriptKindFromFileName;
    /**
     *  List of supported extensions in order of file resolution precedence.
     */
    ts.supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"];
    ts.supportedJavascriptExtensions = [".js", ".jsx"];
    var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions);
    function getSupportedExtensions(options) {
        return options && options.allowJs ? allSupportedExtensions : ts.supportedTypeScriptExtensions;
    }
    ts.getSupportedExtensions = getSupportedExtensions;
    function isSupportedSourceFileName(fileName, compilerOptions) {
        if (!fileName) {
            return false;
        }
        for (var _i = 0, _a = getSupportedExtensions(compilerOptions); _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.
     */
    (function (ExtensionPriority) {
        ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles";
        ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles";
        ExtensionPriority[ExtensionPriority["Limit"] = 5] = "Limit";
        ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest";
        ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest";
    })(ts.ExtensionPriority || (ts.ExtensionPriority = {}));
    var ExtensionPriority = ts.ExtensionPriority;
    function getExtensionPriority(path, supportedExtensions) {
        for (var i = supportedExtensions.length - 1; i >= 0; i--) {
            if (fileExtensionIs(path, supportedExtensions[i])) {
                return adjustExtensionPriority(i);
            }
        }
        // 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) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 0 /* TypeScriptFiles */;
        }
        else if (extensionPriority < 5 /* Limit */) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return 5 /* Limit */;
        }
    }
    ts.adjustExtensionPriority = adjustExtensionPriority;
    /**
     * Gets the next lowest extension priority for a given priority.
     */
    function getNextLowestExtensionPriority(extensionPriority) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return 5 /* Limit */;
        }
    }
    ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority;
    var extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".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) ? path.substring(0, path.length - extension.length) : undefined;
    }
    ts.tryRemoveExtension = tryRemoveExtension;
    function isJsxOrTsxExtension(ext) {
        return ext === ".jsx" || ext === ".tsx";
    }
    ts.isJsxOrTsxExtension = isJsxOrTsxExtension;
    function changeExtension(path, newExtension) {
        return (removeFileExtension(path) + newExtension);
    }
    ts.changeExtension = changeExtension;
    function Symbol(flags, name) {
        this.flags = flags;
        this.name = name;
        this.declarations = undefined;
    }
    function Type(checker, flags) {
        this.flags = flags;
    }
    function Signature(checker) {
    }
    function Node(kind, pos, end) {
        this.kind = kind;
        this.pos = pos;
        this.end = end;
        this.flags = 0 /* None */;
        this.parent = undefined;
    }
    ts.objectAllocator = {
        getNodeConstructor: function () { return Node; },
        getSourceFileConstructor: function () { return Node; },
        getSymbolConstructor: function () { return Symbol; },
        getTypeConstructor: function () { return Type; },
        getSignatureConstructor: function () { return Signature; }
    };
    (function (AssertionLevel) {
        AssertionLevel[AssertionLevel["None"] = 0] = "None";
        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
    })(ts.AssertionLevel || (ts.AssertionLevel = {}));
    var AssertionLevel = ts.AssertionLevel;
    var Debug;
    (function (Debug) {
        var currentAssertionLevel = 0 /* None */;
        function shouldAssert(level) {
            return currentAssertionLevel >= level;
        }
        Debug.shouldAssert = shouldAssert;
        function assert(expression, message, verboseDebugInfo) {
            if (!expression) {
                var verboseDebugString = "";
                if (verboseDebugInfo) {
                    verboseDebugString = "\r\nVerbose Debug Information: " + verboseDebugInfo();
                }
                debugger;
                throw new Error("Debug Failure. False expression: " + (message || "") + verboseDebugString);
            }
        }
        Debug.assert = assert;
        function fail(message) {
            Debug.assert(/*expression*/ false, message);
        }
        Debug.fail = fail;
    })(Debug = ts.Debug || (ts.Debug = {}));
    function copyListRemovingItem(item, list) {
        var copiedList = [];
        for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
            var e = list_1[_i];
            if (e !== item) {
                copiedList.push(e);
            }
        }
        return copiedList;
    }
    ts.copyListRemovingItem = copyListRemovingItem;
    function createGetCanonicalFileName(useCaseSensitivefileNames) {
        return useCaseSensitivefileNames
            ? (function (fileName) { return fileName; })
            : (function (fileName) { return fileName.toLowerCase(); });
    }
    ts.createGetCanonicalFileName = createGetCanonicalFileName;
})(ts || (ts = {}));
/// <reference path="core.ts"/>
var ts;
(function (ts) {
    ts.sys = (function () {
        function getWScriptSystem() {
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            var shell = new ActiveXObject("WScript.Shell");
            var fileStream = new ActiveXObject("ADODB.Stream");
            fileStream.Type = 2 /*text*/;
            var binaryStream = new ActiveXObject("ADODB.Stream");
            binaryStream.Type = 1 /*binary*/;
            var args = [];
            for (var i = 0; i < WScript.Arguments.length; i++) {
                args[i] = WScript.Arguments.Item(i);
            }
            function readFile(fileName, encoding) {
                if (!fso.FileExists(fileName)) {
                    return undefined;
                }
                fileStream.Open();
                try {
                    if (encoding) {
                        fileStream.Charset = encoding;
                        fileStream.LoadFromFile(fileName);
                    }
                    else {
                        // Load file and read the first two bytes into a string with no interpretation
                        fileStream.Charset = "x-ansi";
                        fileStream.LoadFromFile(fileName);
                        var bom = fileStream.ReadText(2) || "";
                        // Position must be at 0 before encoding can be changed
                        fileStream.Position = 0;
                        // [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8
                        fileStream.Charset = bom.length >= 2 && (bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE || bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF) ? "unicode" : "utf-8";
                    }
                    // ReadText method always strips byte order mark from resulting string
                    return fileStream.ReadText();
                }
                catch (e) {
                    throw e;
                }
                finally {
                    fileStream.Close();
                }
            }
            function writeFile(fileName, data, writeByteOrderMark) {
                fileStream.Open();
                binaryStream.Open();
                try {
                    // Write characters in UTF-8 encoding
                    fileStream.Charset = "utf-8";
                    fileStream.WriteText(data);
                    // If we don't want the BOM, then skip it by setting the starting location to 3 (size of BOM).
                    // If not, start from position 0, as the BOM will be added automatically when charset==utf8.
                    if (writeByteOrderMark) {
                        fileStream.Position = 0;
                    }
                    else {
                        fileStream.Position = 3;
                    }
                    fileStream.CopyTo(binaryStream);
                    binaryStream.SaveToFile(fileName, 2 /*overwrite*/);
                }
                finally {
                    binaryStream.Close();
                    fileStream.Close();
                }
            }
            function getNames(collection) {
                var result = [];
                for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
                    result.push(e.item().Name);
                }
                return result.sort();
            }
            function getDirectories(path) {
                var folder = fso.GetFolder(path);
                return getNames(folder.subfolders);
            }
            function getAccessibleFileSystemEntries(path) {
                try {
                    var folder = fso.GetFolder(path || ".");
                    var files = getNames(folder.files);
                    var directories = getNames(folder.subfolders);
                    return { files: files, directories: directories };
                }
                catch (e) {
                    return { files: [], directories: [] };
                }
            }
            function readDirectory(path, extensions, excludes, includes) {
                return ts.matchFiles(path, extensions, excludes, includes, /*useCaseSensitiveFileNames*/ false, shell.CurrentDirectory, getAccessibleFileSystemEntries);
            }
            return {
                args: args,
                newLine: "\r\n",
                useCaseSensitiveFileNames: false,
                write: function (s) {
                    WScript.StdOut.Write(s);
                },
                readFile: readFile,
                writeFile: writeFile,
                resolvePath: function (path) {
                    return fso.GetAbsolutePathName(path);
                },
                fileExists: function (path) {
                    return fso.FileExists(path);
                },
                directoryExists: function (path) {
                    return fso.FolderExists(path);
                },
                createDirectory: function (directoryName) {
                    if (!this.directoryExists(directoryName)) {
                        fso.CreateFolder(directoryName);
                    }
                },
                getExecutingFilePath: function () {
                    return WScript.ScriptFullName;
                },
                getCurrentDirectory: function () {
                    return shell.CurrentDirectory;
                },
                getDirectories: getDirectories,
                readDirectory: readDirectory,
                exit: function (exitCode) {
                    try {
                        WScript.Quit(exitCode);
                    }
                    catch (e) {
                    }
                }
            };
        }
        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 = {};
                // One file can have multiple watchers
                var fileWatcherCallbacks = {};
                return { addFile: addFile, removeFile: removeFile };
                function reduceDirWatcherRefCountForFile(fileName) {
                    var dirName = ts.getDirectoryPath(fileName);
                    if (ts.hasProperty(dirWatchers, dirName)) {
                        var watcher = dirWatchers[dirName];
                        watcher.referenceCount -= 1;
                        if (watcher.referenceCount <= 0) {
                            watcher.close();
                            delete dirWatchers[dirName];
                        }
                    }
                }
                function addDirWatcher(dirPath) {
                    if (ts.hasProperty(dirWatchers, dirPath)) {
                        var watcher_1 = dirWatchers[dirPath];
                        watcher_1.referenceCount += 1;
                        return;
                    }
                    var watcher = _fs.watch(dirPath, { persistent: true }, function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); });
                    watcher.referenceCount = 1;
                    dirWatchers[dirPath] = watcher;
                    return;
                }
                function addFileWatcherCallback(filePath, callback) {
                    if (ts.hasProperty(fileWatcherCallbacks, filePath)) {
                        fileWatcherCallbacks[filePath].push(callback);
                    }
                    else {
                        fileWatcherCallbacks[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) {
                    if (ts.hasProperty(fileWatcherCallbacks, filePath)) {
                        var newCallbacks = ts.copyListRemovingItem(callback, fileWatcherCallbacks[filePath]);
                        if (newCallbacks.length === 0) {
                            delete fileWatcherCallbacks[filePath];
                        }
                        else {
                            fileWatcherCallbacks[filePath] = newCallbacks;
                        }
                    }
                }
                function fileEventHandler(eventName, relativeFileName, baseDirPath) {
                    // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
                    var fileName = typeof relativeFileName !== "string"
                        ? undefined
                        : ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath);
                    // Some applications save a working file via rename operations
                    if ((eventName === "change" || eventName === "rename") && ts.hasProperty(fileWatcherCallbacks, fileName)) {
                        for (var _i = 0, _a = fileWatcherCallbacks[fileName]; _i < _a.length; _i++) {
                            var fileCallback = _a[_i];
                            fileCallback(fileName);
                        }
                    }
                }
            }
            var watchedFileSet = createWatchedFileSet();
            function isNode4OrLater() {
                return parseInt(process.version.charAt(1)) >= 4;
            }
            var platform = _os.platform();
            // win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive
            var useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
            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;
                    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, 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_3 = ts.combinePaths(path, entry);
                        var stat = void 0;
                        try {
                            stat = _fs.statSync(name_3);
                        }
                        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) {
                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), 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 (p) { return fileSystemEntryExists(ts.combinePaths(path, p), 1 /* Directory */); });
            }
            return {
                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) {
                    if (useNonPollingWatchers) {
                        var watchedFile_1 = watchedFileSet.addFile(fileName, callback);
                        return {
                            close: function () { return watchedFileSet.removeFile(watchedFile_1); }
                        };
                    }
                    else {
                        _fs.watchFile(fileName, { persistent: true, interval: 250 }, fileChanged);
                        return {
                            close: function () { return _fs.unwatchFile(fileName, fileChanged); }
                        };
                    }
                    function fileChanged(curr, prev) {
                        if (+curr.mtime <= +prev.mtime) {
                            return;
                        }
                        callback(fileName);
                    }
                },
                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)
                    var options;
                    if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
                        options = { persistent: true, recursive: !!recursive };
                    }
                    else {
                        options = { persistent: true };
                    }
                    return _fs.watch(directoryName, options, 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)));
                        }
                        ;
                    });
                },
                resolvePath: function (path) {
                    return _path.resolve(path);
                },
                fileExists: fileExists,
                directoryExists: directoryExists,
                createDirectory: function (directoryName) {
                    if (!this.directoryExists(directoryName)) {
                        _fs.mkdirSync(directoryName);
                    }
                },
                getExecutingFilePath: function () {
                    return __filename;
                },
                getCurrentDirectory: function () {
                    return process.cwd();
                },
                getDirectories: getDirectories,
                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);
                }
            };
        }
        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,
                readDirectory: function (path, extensions, excludes, includes) {
                    var pattern = ts.getFileMatcherPatterns(path, extensions, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
                    return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
                },
                exit: ChakraHost.quit,
                realpath: realpath
            };
        }
        if (typeof ChakraHost !== "undefined") {
            return getChakraSystem();
        }
        else if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
            return getWScriptSystem();
        }
        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
            return getNodeSystem();
        }
        else {
            return undefined; // Unsupported host
        }
    })();
})(ts || (ts = {}));
// <auto-generated />
/// <reference path="types.ts" />
/* @internal */
var ts;
(function (ts) {
    ts.Diagnostics = {
        Unterminated_string_literal: { code: 1002, category: ts.DiagnosticCategory.Error, key: "Unterminated_string_literal_1002", message: "Unterminated string literal." },
        Identifier_expected: { code: 1003, category: ts.DiagnosticCategory.Error, key: "Identifier_expected_1003", message: "Identifier expected." },
        _0_expected: { code: 1005, category: ts.DiagnosticCategory.Error, key: "_0_expected_1005", message: "'{0}' expected." },
        A_file_cannot_have_a_reference_to_itself: { code: 1006, category: ts.DiagnosticCategory.Error, key: "A_file_cannot_have_a_reference_to_itself_1006", message: "A file cannot have a reference to itself." },
        Trailing_comma_not_allowed: { code: 1009, category: ts.DiagnosticCategory.Error, key: "Trailing_comma_not_allowed_1009", message: "Trailing comma not allowed." },
        Asterisk_Slash_expected: { code: 1010, category: ts.DiagnosticCategory.Error, key: "Asterisk_Slash_expected_1010", message: "'*/' expected." },
        Unexpected_token: { code: 1012, category: ts.DiagnosticCategory.Error, key: "Unexpected_token_1012", message: "Unexpected token." },
        A_rest_parameter_must_be_last_in_a_parameter_list: { code: 1014, category: ts.DiagnosticCategory.Error, key: "A_rest_parameter_must_be_last_in_a_parameter_list_1014", message: "A rest parameter must be last in a parameter list." },
        Parameter_cannot_have_question_mark_and_initializer: { code: 1015, category: ts.DiagnosticCategory.Error, key: "Parameter_cannot_have_question_mark_and_initializer_1015", message: "Parameter cannot have question mark and initializer." },
        A_required_parameter_cannot_follow_an_optional_parameter: { code: 1016, category: ts.DiagnosticCategory.Error, key: "A_required_parameter_cannot_follow_an_optional_parameter_1016", message: "A required parameter cannot follow an optional parameter." },
        An_index_signature_cannot_have_a_rest_parameter: { code: 1017, category: ts.DiagnosticCategory.Error, key: "An_index_signature_cannot_have_a_rest_parameter_1017", message: "An index signature cannot have a rest parameter." },
        An_index_signature_parameter_cannot_have_an_accessibility_modifier: { code: 1018, category: ts.DiagnosticCategory.Error, key: "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", message: "An index signature parameter cannot have an accessibility modifier." },
        An_index_signature_parameter_cannot_have_a_question_mark: { code: 1019, category: ts.DiagnosticCategory.Error, key: "An_index_signature_parameter_cannot_have_a_question_mark_1019", message: "An index signature parameter cannot have a question mark." },
        An_index_signature_parameter_cannot_have_an_initializer: { code: 1020, category: ts.DiagnosticCategory.Error, key: "An_index_signature_parameter_cannot_have_an_initializer_1020", message: "An index signature parameter cannot have an initializer." },
        An_index_signature_must_have_a_type_annotation: { code: 1021, category: ts.DiagnosticCategory.Error, key: "An_index_signature_must_have_a_type_annotation_1021", message: "An index signature must have a type annotation." },
        An_index_signature_parameter_must_have_a_type_annotation: { code: 1022, category: ts.DiagnosticCategory.Error, key: "An_index_signature_parameter_must_have_a_type_annotation_1022", message: "An index signature parameter must have a type annotation." },
        An_index_signature_parameter_type_must_be_string_or_number: { code: 1023, category: ts.DiagnosticCategory.Error, key: "An_index_signature_parameter_type_must_be_string_or_number_1023", message: "An index signature parameter type must be 'string' or 'number'." },
        readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: { code: 1024, category: ts.DiagnosticCategory.Error, key: "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", message: "'readonly' modifier can only appear on a property declaration or index signature." },
        Accessibility_modifier_already_seen: { code: 1028, category: ts.DiagnosticCategory.Error, key: "Accessibility_modifier_already_seen_1028", message: "Accessibility modifier already seen." },
        _0_modifier_must_precede_1_modifier: { code: 1029, category: ts.DiagnosticCategory.Error, key: "_0_modifier_must_precede_1_modifier_1029", message: "'{0}' modifier must precede '{1}' modifier." },
        _0_modifier_already_seen: { code: 1030, category: ts.DiagnosticCategory.Error, key: "_0_modifier_already_seen_1030", message: "'{0}' modifier already seen." },
        _0_modifier_cannot_appear_on_a_class_element: { code: 1031, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_a_class_element_1031", message: "'{0}' modifier cannot appear on a class element." },
        super_must_be_followed_by_an_argument_list_or_member_access: { code: 1034, category: ts.DiagnosticCategory.Error, key: "super_must_be_followed_by_an_argument_list_or_member_access_1034", message: "'super' must be followed by an argument list or member access." },
        Only_ambient_modules_can_use_quoted_names: { code: 1035, category: ts.DiagnosticCategory.Error, key: "Only_ambient_modules_can_use_quoted_names_1035", message: "Only ambient modules can use quoted names." },
        Statements_are_not_allowed_in_ambient_contexts: { code: 1036, category: ts.DiagnosticCategory.Error, key: "Statements_are_not_allowed_in_ambient_contexts_1036", message: "Statements are not allowed in ambient contexts." },
        A_declare_modifier_cannot_be_used_in_an_already_ambient_context: { code: 1038, category: ts.DiagnosticCategory.Error, key: "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", message: "A 'declare' modifier cannot be used in an already ambient context." },
        Initializers_are_not_allowed_in_ambient_contexts: { code: 1039, category: ts.DiagnosticCategory.Error, key: "Initializers_are_not_allowed_in_ambient_contexts_1039", message: "Initializers are not allowed in ambient contexts." },
        _0_modifier_cannot_be_used_in_an_ambient_context: { code: 1040, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_be_used_in_an_ambient_context_1040", message: "'{0}' modifier cannot be used in an ambient context." },
        _0_modifier_cannot_be_used_with_a_class_declaration: { code: 1041, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_be_used_with_a_class_declaration_1041", message: "'{0}' modifier cannot be used with a class declaration." },
        _0_modifier_cannot_be_used_here: { code: 1042, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_be_used_here_1042", message: "'{0}' modifier cannot be used here." },
        _0_modifier_cannot_appear_on_a_data_property: { code: 1043, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_a_data_property_1043", message: "'{0}' modifier cannot appear on a data property." },
        _0_modifier_cannot_appear_on_a_module_or_namespace_element: { code: 1044, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", message: "'{0}' modifier cannot appear on a module or namespace element." },
        A_0_modifier_cannot_be_used_with_an_interface_declaration: { code: 1045, category: ts.DiagnosticCategory.Error, key: "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", message: "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: { code: 1046, category: ts.DiagnosticCategory.Error, key: "A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046", message: "A 'declare' modifier is required for a top level declaration in a .d.ts file." },
        A_rest_parameter_cannot_be_optional: { code: 1047, category: ts.DiagnosticCategory.Error, key: "A_rest_parameter_cannot_be_optional_1047", message: "A rest parameter cannot be optional." },
        A_rest_parameter_cannot_have_an_initializer: { code: 1048, category: ts.DiagnosticCategory.Error, key: "A_rest_parameter_cannot_have_an_initializer_1048", message: "A rest parameter cannot have an initializer." },
        A_set_accessor_must_have_exactly_one_parameter: { code: 1049, category: ts.DiagnosticCategory.Error, key: "A_set_accessor_must_have_exactly_one_parameter_1049", message: "A 'set' accessor must have exactly one parameter." },
        A_set_accessor_cannot_have_an_optional_parameter: { code: 1051, category: ts.DiagnosticCategory.Error, key: "A_set_accessor_cannot_have_an_optional_parameter_1051", message: "A 'set' accessor cannot have an optional parameter." },
        A_set_accessor_parameter_cannot_have_an_initializer: { code: 1052, category: ts.DiagnosticCategory.Error, key: "A_set_accessor_parameter_cannot_have_an_initializer_1052", message: "A 'set' accessor parameter cannot have an initializer." },
        A_set_accessor_cannot_have_rest_parameter: { code: 1053, category: ts.DiagnosticCategory.Error, key: "A_set_accessor_cannot_have_rest_parameter_1053", message: "A 'set' accessor cannot have rest parameter." },
        A_get_accessor_cannot_have_parameters: { code: 1054, category: ts.DiagnosticCategory.Error, key: "A_get_accessor_cannot_have_parameters_1054", message: "A 'get' accessor cannot have parameters." },
        Type_0_is_not_a_valid_async_function_return_type: { code: 1055, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_a_valid_async_function_return_type_1055", message: "Type '{0}' is not a valid async function return type." },
        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1056, category: ts.DiagnosticCategory.Error, key: "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", message: "Accessors are only available when targeting ECMAScript 5 and higher." },
        An_async_function_or_method_must_have_a_valid_awaitable_return_type: { code: 1057, category: ts.DiagnosticCategory.Error, key: "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", message: "An async function or method must have a valid awaitable return type." },
        Operand_for_await_does_not_have_a_valid_callable_then_member: { code: 1058, category: ts.DiagnosticCategory.Error, key: "Operand_for_await_does_not_have_a_valid_callable_then_member_1058", message: "Operand for 'await' does not have a valid callable 'then' member." },
        Return_expression_in_async_function_does_not_have_a_valid_callable_then_member: { code: 1059, category: ts.DiagnosticCategory.Error, key: "Return_expression_in_async_function_does_not_have_a_valid_callable_then_member_1059", message: "Return expression in async function does not have a valid callable 'then' member." },
        Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member: { code: 1060, category: ts.DiagnosticCategory.Error, key: "Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member_1060", message: "Expression body for async arrow function does not have a valid callable 'then' member." },
        Enum_member_must_have_initializer: { code: 1061, category: ts.DiagnosticCategory.Error, key: "Enum_member_must_have_initializer_1061", message: "Enum member must have initializer." },
        _0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: { code: 1062, category: ts.DiagnosticCategory.Error, key: "_0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", message: "{0} is referenced directly or indirectly in the fulfillment callback of its own 'then' method." },
        An_export_assignment_cannot_be_used_in_a_namespace: { code: 1063, category: ts.DiagnosticCategory.Error, key: "An_export_assignment_cannot_be_used_in_a_namespace_1063", message: "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: { code: 1064, category: ts.DiagnosticCategory.Error, key: "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", message: "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: { code: 1066, category: ts.DiagnosticCategory.Error, key: "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", message: "In ambient enum declarations member initializer must be constant expression." },
        Unexpected_token_A_constructor_method_accessor_or_property_was_expected: { code: 1068, category: ts.DiagnosticCategory.Error, key: "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", message: "Unexpected token. A constructor, method, accessor, or property was expected." },
        _0_modifier_cannot_appear_on_a_type_member: { code: 1070, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_a_type_member_1070", message: "'{0}' modifier cannot appear on a type member." },
        _0_modifier_cannot_appear_on_an_index_signature: { code: 1071, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_an_index_signature_1071", message: "'{0}' modifier cannot appear on an index signature." },
        A_0_modifier_cannot_be_used_with_an_import_declaration: { code: 1079, category: ts.DiagnosticCategory.Error, key: "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", message: "A '{0}' modifier cannot be used with an import declaration." },
        Invalid_reference_directive_syntax: { code: 1084, category: ts.DiagnosticCategory.Error, key: "Invalid_reference_directive_syntax_1084", message: "Invalid 'reference' directive syntax." },
        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher: { code: 1085, category: ts.DiagnosticCategory.Error, key: "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_1085", message: "Octal literals are not available when targeting ECMAScript 5 and higher." },
        An_accessor_cannot_be_declared_in_an_ambient_context: { code: 1086, category: ts.DiagnosticCategory.Error, key: "An_accessor_cannot_be_declared_in_an_ambient_context_1086", message: "An accessor cannot be declared in an ambient context." },
        _0_modifier_cannot_appear_on_a_constructor_declaration: { code: 1089, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", message: "'{0}' modifier cannot appear on a constructor declaration." },
        _0_modifier_cannot_appear_on_a_parameter: { code: 1090, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_appear_on_a_parameter_1090", message: "'{0}' modifier cannot appear on a parameter." },
        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: { code: 1091, category: ts.DiagnosticCategory.Error, key: "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", message: "Only a single variable declaration is allowed in a 'for...in' statement." },
        Type_parameters_cannot_appear_on_a_constructor_declaration: { code: 1092, category: ts.DiagnosticCategory.Error, key: "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", message: "Type parameters cannot appear on a constructor declaration." },
        Type_annotation_cannot_appear_on_a_constructor_declaration: { code: 1093, category: ts.DiagnosticCategory.Error, key: "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", message: "Type annotation cannot appear on a constructor declaration." },
        An_accessor_cannot_have_type_parameters: { code: 1094, category: ts.DiagnosticCategory.Error, key: "An_accessor_cannot_have_type_parameters_1094", message: "An accessor cannot have type parameters." },
        A_set_accessor_cannot_have_a_return_type_annotation: { code: 1095, category: ts.DiagnosticCategory.Error, key: "A_set_accessor_cannot_have_a_return_type_annotation_1095", message: "A 'set' accessor cannot have a return type annotation." },
        An_index_signature_must_have_exactly_one_parameter: { code: 1096, category: ts.DiagnosticCategory.Error, key: "An_index_signature_must_have_exactly_one_parameter_1096", message: "An index signature must have exactly one parameter." },
        _0_list_cannot_be_empty: { code: 1097, category: ts.DiagnosticCategory.Error, key: "_0_list_cannot_be_empty_1097", message: "'{0}' list cannot be empty." },
        Type_parameter_list_cannot_be_empty: { code: 1098, category: ts.DiagnosticCategory.Error, key: "Type_parameter_list_cannot_be_empty_1098", message: "Type parameter list cannot be empty." },
        Type_argument_list_cannot_be_empty: { code: 1099, category: ts.DiagnosticCategory.Error, key: "Type_argument_list_cannot_be_empty_1099", message: "Type argument list cannot be empty." },
        Invalid_use_of_0_in_strict_mode: { code: 1100, category: ts.DiagnosticCategory.Error, key: "Invalid_use_of_0_in_strict_mode_1100", message: "Invalid use of '{0}' in strict mode." },
        with_statements_are_not_allowed_in_strict_mode: { code: 1101, category: ts.DiagnosticCategory.Error, key: "with_statements_are_not_allowed_in_strict_mode_1101", message: "'with' statements are not allowed in strict mode." },
        delete_cannot_be_called_on_an_identifier_in_strict_mode: { code: 1102, category: ts.DiagnosticCategory.Error, key: "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", message: "'delete' cannot be called on an identifier in strict mode." },
        A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: { code: 1104, category: ts.DiagnosticCategory.Error, key: "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", message: "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: { code: 1105, category: ts.DiagnosticCategory.Error, key: "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", message: "A 'break' statement can only be used within an enclosing iteration or switch statement." },
        Jump_target_cannot_cross_function_boundary: { code: 1107, category: ts.DiagnosticCategory.Error, key: "Jump_target_cannot_cross_function_boundary_1107", message: "Jump target cannot cross function boundary." },
        A_return_statement_can_only_be_used_within_a_function_body: { code: 1108, category: ts.DiagnosticCategory.Error, key: "A_return_statement_can_only_be_used_within_a_function_body_1108", message: "A 'return' statement can only be used within a function body." },
        Expression_expected: { code: 1109, category: ts.DiagnosticCategory.Error, key: "Expression_expected_1109", message: "Expression expected." },
        Type_expected: { code: 1110, category: ts.DiagnosticCategory.Error, key: "Type_expected_1110", message: "Type expected." },
        A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: { code: 1113, category: ts.DiagnosticCategory.Error, key: "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", message: "A 'default' clause cannot appear more than once in a 'switch' statement." },
        Duplicate_label_0: { code: 1114, category: ts.DiagnosticCategory.Error, key: "Duplicate_label_0_1114", message: "Duplicate label '{0}'" },
        A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: { code: 1115, category: ts.DiagnosticCategory.Error, key: "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", message: "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: { code: 1116, category: ts.DiagnosticCategory.Error, key: "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", message: "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: { code: 1117, category: ts.DiagnosticCategory.Error, key: "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", message: "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: { code: 1118, category: ts.DiagnosticCategory.Error, key: "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", message: "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: { code: 1119, category: ts.DiagnosticCategory.Error, key: "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", message: "An object literal cannot have property and accessor with the same name." },
        An_export_assignment_cannot_have_modifiers: { code: 1120, category: ts.DiagnosticCategory.Error, key: "An_export_assignment_cannot_have_modifiers_1120", message: "An export assignment cannot have modifiers." },
        Octal_literals_are_not_allowed_in_strict_mode: { code: 1121, category: ts.DiagnosticCategory.Error, key: "Octal_literals_are_not_allowed_in_strict_mode_1121", message: "Octal literals are not allowed in strict mode." },
        A_tuple_type_element_list_cannot_be_empty: { code: 1122, category: ts.DiagnosticCategory.Error, key: "A_tuple_type_element_list_cannot_be_empty_1122", message: "A tuple type element list cannot be empty." },
        Variable_declaration_list_cannot_be_empty: { code: 1123, category: ts.DiagnosticCategory.Error, key: "Variable_declaration_list_cannot_be_empty_1123", message: "Variable declaration list cannot be empty." },
        Digit_expected: { code: 1124, category: ts.DiagnosticCategory.Error, key: "Digit_expected_1124", message: "Digit expected." },
        Hexadecimal_digit_expected: { code: 1125, category: ts.DiagnosticCategory.Error, key: "Hexadecimal_digit_expected_1125", message: "Hexadecimal digit expected." },
        Unexpected_end_of_text: { code: 1126, category: ts.DiagnosticCategory.Error, key: "Unexpected_end_of_text_1126", message: "Unexpected end of text." },
        Invalid_character: { code: 1127, category: ts.DiagnosticCategory.Error, key: "Invalid_character_1127", message: "Invalid character." },
        Declaration_or_statement_expected: { code: 1128, category: ts.DiagnosticCategory.Error, key: "Declaration_or_statement_expected_1128", message: "Declaration or statement expected." },
        Statement_expected: { code: 1129, category: ts.DiagnosticCategory.Error, key: "Statement_expected_1129", message: "Statement expected." },
        case_or_default_expected: { code: 1130, category: ts.DiagnosticCategory.Error, key: "case_or_default_expected_1130", message: "'case' or 'default' expected." },
        Property_or_signature_expected: { code: 1131, category: ts.DiagnosticCategory.Error, key: "Property_or_signature_expected_1131", message: "Property or signature expected." },
        Enum_member_expected: { code: 1132, category: ts.DiagnosticCategory.Error, key: "Enum_member_expected_1132", message: "Enum member expected." },
        Variable_declaration_expected: { code: 1134, category: ts.DiagnosticCategory.Error, key: "Variable_declaration_expected_1134", message: "Variable declaration expected." },
        Argument_expression_expected: { code: 1135, category: ts.DiagnosticCategory.Error, key: "Argument_expression_expected_1135", message: "Argument expression expected." },
        Property_assignment_expected: { code: 1136, category: ts.DiagnosticCategory.Error, key: "Property_assignment_expected_1136", message: "Property assignment expected." },
        Expression_or_comma_expected: { code: 1137, category: ts.DiagnosticCategory.Error, key: "Expression_or_comma_expected_1137", message: "Expression or comma expected." },
        Parameter_declaration_expected: { code: 1138, category: ts.DiagnosticCategory.Error, key: "Parameter_declaration_expected_1138", message: "Parameter declaration expected." },
        Type_parameter_declaration_expected: { code: 1139, category: ts.DiagnosticCategory.Error, key: "Type_parameter_declaration_expected_1139", message: "Type parameter declaration expected." },
        Type_argument_expected: { code: 1140, category: ts.DiagnosticCategory.Error, key: "Type_argument_expected_1140", message: "Type argument expected." },
        String_literal_expected: { code: 1141, category: ts.DiagnosticCategory.Error, key: "String_literal_expected_1141", message: "String literal expected." },
        Line_break_not_permitted_here: { code: 1142, category: ts.DiagnosticCategory.Error, key: "Line_break_not_permitted_here_1142", message: "Line break not permitted here." },
        or_expected: { code: 1144, category: ts.DiagnosticCategory.Error, key: "or_expected_1144", message: "'{' or ';' expected." },
        Declaration_expected: { code: 1146, category: ts.DiagnosticCategory.Error, key: "Declaration_expected_1146", message: "Declaration expected." },
        Import_declarations_in_a_namespace_cannot_reference_a_module: { code: 1147, category: ts.DiagnosticCategory.Error, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", message: "Import declarations in a namespace cannot reference a module." },
        Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: { code: 1148, category: ts.DiagnosticCategory.Error, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", message: "Cannot use imports, exports, or module augmentations when '--module' is 'none'." },
        File_name_0_differs_from_already_included_file_name_1_only_in_casing: { code: 1149, category: ts.DiagnosticCategory.Error, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", message: "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: { code: 1150, category: ts.DiagnosticCategory.Error, key: "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", message: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
        const_declarations_must_be_initialized: { code: 1155, category: ts.DiagnosticCategory.Error, key: "const_declarations_must_be_initialized_1155", message: "'const' declarations must be initialized" },
        const_declarations_can_only_be_declared_inside_a_block: { code: 1156, category: ts.DiagnosticCategory.Error, key: "const_declarations_can_only_be_declared_inside_a_block_1156", message: "'const' declarations can only be declared inside a block." },
        let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: ts.DiagnosticCategory.Error, key: "let_declarations_can_only_be_declared_inside_a_block_1157", message: "'let' declarations can only be declared inside a block." },
        Unterminated_template_literal: { code: 1160, category: ts.DiagnosticCategory.Error, key: "Unterminated_template_literal_1160", message: "Unterminated template literal." },
        Unterminated_regular_expression_literal: { code: 1161, category: ts.DiagnosticCategory.Error, key: "Unterminated_regular_expression_literal_1161", message: "Unterminated regular expression literal." },
        An_object_member_cannot_be_declared_optional: { code: 1162, category: ts.DiagnosticCategory.Error, key: "An_object_member_cannot_be_declared_optional_1162", message: "An object member cannot be declared optional." },
        A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: ts.DiagnosticCategory.Error, key: "A_yield_expression_is_only_allowed_in_a_generator_body_1163", message: "A 'yield' expression is only allowed in a generator body." },
        Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: ts.DiagnosticCategory.Error, key: "Computed_property_names_are_not_allowed_in_enums_1164", message: "Computed property names are not allowed in enums." },
        A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol_1165", message: "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: { code: 1166, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol_1166", message: "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: { code: 1168, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol_1168", message: "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: { code: 1169, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol_1169", message: "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: { code: 1170, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol_1170", message: "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: { code: 1171, category: ts.DiagnosticCategory.Error, key: "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", message: "A comma expression is not allowed in a computed property name." },
        extends_clause_already_seen: { code: 1172, category: ts.DiagnosticCategory.Error, key: "extends_clause_already_seen_1172", message: "'extends' clause already seen." },
        extends_clause_must_precede_implements_clause: { code: 1173, category: ts.DiagnosticCategory.Error, key: "extends_clause_must_precede_implements_clause_1173", message: "'extends' clause must precede 'implements' clause." },
        Classes_can_only_extend_a_single_class: { code: 1174, category: ts.DiagnosticCategory.Error, key: "Classes_can_only_extend_a_single_class_1174", message: "Classes can only extend a single class." },
        implements_clause_already_seen: { code: 1175, category: ts.DiagnosticCategory.Error, key: "implements_clause_already_seen_1175", message: "'implements' clause already seen." },
        Interface_declaration_cannot_have_implements_clause: { code: 1176, category: ts.DiagnosticCategory.Error, key: "Interface_declaration_cannot_have_implements_clause_1176", message: "Interface declaration cannot have 'implements' clause." },
        Binary_digit_expected: { code: 1177, category: ts.DiagnosticCategory.Error, key: "Binary_digit_expected_1177", message: "Binary digit expected." },
        Octal_digit_expected: { code: 1178, category: ts.DiagnosticCategory.Error, key: "Octal_digit_expected_1178", message: "Octal digit expected." },
        Unexpected_token_expected: { code: 1179, category: ts.DiagnosticCategory.Error, key: "Unexpected_token_expected_1179", message: "Unexpected token. '{' expected." },
        Property_destructuring_pattern_expected: { code: 1180, category: ts.DiagnosticCategory.Error, key: "Property_destructuring_pattern_expected_1180", message: "Property destructuring pattern expected." },
        Array_element_destructuring_pattern_expected: { code: 1181, category: ts.DiagnosticCategory.Error, key: "Array_element_destructuring_pattern_expected_1181", message: "Array element destructuring pattern expected." },
        A_destructuring_declaration_must_have_an_initializer: { code: 1182, category: ts.DiagnosticCategory.Error, key: "A_destructuring_declaration_must_have_an_initializer_1182", message: "A destructuring declaration must have an initializer." },
        An_implementation_cannot_be_declared_in_ambient_contexts: { code: 1183, category: ts.DiagnosticCategory.Error, key: "An_implementation_cannot_be_declared_in_ambient_contexts_1183", message: "An implementation cannot be declared in ambient contexts." },
        Modifiers_cannot_appear_here: { code: 1184, category: ts.DiagnosticCategory.Error, key: "Modifiers_cannot_appear_here_1184", message: "Modifiers cannot appear here." },
        Merge_conflict_marker_encountered: { code: 1185, category: ts.DiagnosticCategory.Error, key: "Merge_conflict_marker_encountered_1185", message: "Merge conflict marker encountered." },
        A_rest_element_cannot_have_an_initializer: { code: 1186, category: ts.DiagnosticCategory.Error, key: "A_rest_element_cannot_have_an_initializer_1186", message: "A rest element cannot have an initializer." },
        A_parameter_property_may_not_be_declared_using_a_binding_pattern: { code: 1187, category: ts.DiagnosticCategory.Error, key: "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", message: "A parameter property may not be declared using a binding pattern." },
        Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: { code: 1188, category: ts.DiagnosticCategory.Error, key: "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", message: "Only a single variable declaration is allowed in a 'for...of' statement." },
        The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: { code: 1189, category: ts.DiagnosticCategory.Error, key: "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", message: "The variable declaration of a 'for...in' statement cannot have an initializer." },
        The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: { code: 1190, category: ts.DiagnosticCategory.Error, key: "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", message: "The variable declaration of a 'for...of' statement cannot have an initializer." },
        An_import_declaration_cannot_have_modifiers: { code: 1191, category: ts.DiagnosticCategory.Error, key: "An_import_declaration_cannot_have_modifiers_1191", message: "An import declaration cannot have modifiers." },
        Module_0_has_no_default_export: { code: 1192, category: ts.DiagnosticCategory.Error, key: "Module_0_has_no_default_export_1192", message: "Module '{0}' has no default export." },
        An_export_declaration_cannot_have_modifiers: { code: 1193, category: ts.DiagnosticCategory.Error, key: "An_export_declaration_cannot_have_modifiers_1193", message: "An export declaration cannot have modifiers." },
        Export_declarations_are_not_permitted_in_a_namespace: { code: 1194, category: ts.DiagnosticCategory.Error, key: "Export_declarations_are_not_permitted_in_a_namespace_1194", message: "Export declarations are not permitted in a namespace." },
        Catch_clause_variable_name_must_be_an_identifier: { code: 1195, category: ts.DiagnosticCategory.Error, key: "Catch_clause_variable_name_must_be_an_identifier_1195", message: "Catch clause variable name must be an identifier." },
        Catch_clause_variable_cannot_have_a_type_annotation: { code: 1196, category: ts.DiagnosticCategory.Error, key: "Catch_clause_variable_cannot_have_a_type_annotation_1196", message: "Catch clause variable cannot have a type annotation." },
        Catch_clause_variable_cannot_have_an_initializer: { code: 1197, category: ts.DiagnosticCategory.Error, key: "Catch_clause_variable_cannot_have_an_initializer_1197", message: "Catch clause variable cannot have an initializer." },
        An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: { code: 1198, category: ts.DiagnosticCategory.Error, key: "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", message: "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive." },
        Unterminated_Unicode_escape_sequence: { code: 1199, category: ts.DiagnosticCategory.Error, key: "Unterminated_Unicode_escape_sequence_1199", message: "Unterminated Unicode escape sequence." },
        Line_terminator_not_permitted_before_arrow: { code: 1200, category: ts.DiagnosticCategory.Error, key: "Line_terminator_not_permitted_before_arrow_1200", message: "Line terminator not permitted before arrow." },
        Import_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: { code: 1202, category: ts.DiagnosticCategory.Error, key: "Import_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_import_Asteri_1202", message: "Import assignment cannot be used when targeting ECMAScript 2015 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_2015_modules_Consider_using_export_default_or_another_module_format_instead: { code: 1203, category: ts.DiagnosticCategory.Error, key: "Export_assignment_cannot_be_used_when_targeting_ECMAScript_2015_modules_Consider_using_export_defaul_1203", message: "Export assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'export default' or another module format instead." },
        Decorators_are_not_valid_here: { code: 1206, category: ts.DiagnosticCategory.Error, key: "Decorators_are_not_valid_here_1206", message: "Decorators are not valid here." },
        Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: ts.DiagnosticCategory.Error, key: "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", message: "Decorators cannot be applied to multiple get/set accessors of the same name." },
        Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided_1208", message: "Cannot compile namespaces when the '--isolatedModules' flag is provided." },
        Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided_1209", message: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." },
        Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: ts.DiagnosticCategory.Error, key: "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", message: "Invalid use of '{0}'. Class definitions are automatically in strict mode." },
        A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: ts.DiagnosticCategory.Error, key: "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", message: "A class declaration without the 'default' modifier must have a name" },
        Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: ts.DiagnosticCategory.Error, key: "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", message: "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: { code: 1213, category: ts.DiagnosticCategory.Error, key: "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", message: "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: { code: 1214, category: ts.DiagnosticCategory.Error, key: "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", message: "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: { code: 1215, category: ts.DiagnosticCategory.Error, key: "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", message: "Invalid use of '{0}'. Modules are automatically in strict mode." },
        Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export_assignment_is_not_supported_when_module_flag_is_system_1218", message: "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: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", message: "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: { code: 1220, category: ts.DiagnosticCategory.Error, key: "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", message: "Generators are only available when targeting ECMAScript 2015 or higher." },
        Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: ts.DiagnosticCategory.Error, key: "Generators_are_not_allowed_in_an_ambient_context_1221", message: "Generators are not allowed in an ambient context." },
        An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: ts.DiagnosticCategory.Error, key: "An_overload_signature_cannot_be_declared_as_a_generator_1222", message: "An overload signature cannot be declared as a generator." },
        _0_tag_already_specified: { code: 1223, category: ts.DiagnosticCategory.Error, key: "_0_tag_already_specified_1223", message: "'{0}' tag already specified." },
        Signature_0_must_have_a_type_predicate: { code: 1224, category: ts.DiagnosticCategory.Error, key: "Signature_0_must_have_a_type_predicate_1224", message: "Signature '{0}' must have a type predicate." },
        Cannot_find_parameter_0: { code: 1225, category: ts.DiagnosticCategory.Error, key: "Cannot_find_parameter_0_1225", message: "Cannot find parameter '{0}'." },
        Type_predicate_0_is_not_assignable_to_1: { code: 1226, category: ts.DiagnosticCategory.Error, key: "Type_predicate_0_is_not_assignable_to_1_1226", message: "Type predicate '{0}' is not assignable to '{1}'." },
        Parameter_0_is_not_in_the_same_position_as_parameter_1: { code: 1227, category: ts.DiagnosticCategory.Error, key: "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", message: "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: { code: 1228, category: ts.DiagnosticCategory.Error, key: "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", message: "A type predicate is only allowed in return type position for functions and methods." },
        A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: ts.DiagnosticCategory.Error, key: "A_type_predicate_cannot_reference_a_rest_parameter_1229", message: "A type predicate cannot reference a rest parameter." },
        A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: ts.DiagnosticCategory.Error, key: "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", message: "A type predicate cannot reference element '{0}' in a binding pattern." },
        An_export_assignment_can_only_be_used_in_a_module: { code: 1231, category: ts.DiagnosticCategory.Error, key: "An_export_assignment_can_only_be_used_in_a_module_1231", message: "An export assignment can only be used in a module." },
        An_import_declaration_can_only_be_used_in_a_namespace_or_module: { code: 1232, category: ts.DiagnosticCategory.Error, key: "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", message: "An import declaration can only be used in a namespace or module." },
        An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: ts.DiagnosticCategory.Error, key: "An_export_declaration_can_only_be_used_in_a_module_1233", message: "An export declaration can only be used in a module." },
        An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: ts.DiagnosticCategory.Error, key: "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", message: "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: { code: 1235, category: ts.DiagnosticCategory.Error, key: "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", message: "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: { code: 1236, category: ts.DiagnosticCategory.Error, key: "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", message: "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: { code: 1237, category: ts.DiagnosticCategory.Error, key: "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", message: "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: { code: 1238, category: ts.DiagnosticCategory.Error, key: "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", message: "Unable to resolve signature of class decorator when called as an expression." },
        Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: { code: 1239, category: ts.DiagnosticCategory.Error, key: "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", message: "Unable to resolve signature of parameter decorator when called as an expression." },
        Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: { code: 1240, category: ts.DiagnosticCategory.Error, key: "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", message: "Unable to resolve signature of property decorator when called as an expression." },
        Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: { code: 1241, category: ts.DiagnosticCategory.Error, key: "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", message: "Unable to resolve signature of method decorator when called as an expression." },
        abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: { code: 1242, category: ts.DiagnosticCategory.Error, key: "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", message: "'abstract' modifier can only appear on a class, method, or property declaration." },
        _0_modifier_cannot_be_used_with_1_modifier: { code: 1243, category: ts.DiagnosticCategory.Error, key: "_0_modifier_cannot_be_used_with_1_modifier_1243", message: "'{0}' modifier cannot be used with '{1}' modifier." },
        Abstract_methods_can_only_appear_within_an_abstract_class: { code: 1244, category: ts.DiagnosticCategory.Error, key: "Abstract_methods_can_only_appear_within_an_abstract_class_1244", message: "Abstract methods can only appear within an abstract class." },
        Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: { code: 1245, category: ts.DiagnosticCategory.Error, key: "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", message: "Method '{0}' cannot have an implementation because it is marked abstract." },
        An_interface_property_cannot_have_an_initializer: { code: 1246, category: ts.DiagnosticCategory.Error, key: "An_interface_property_cannot_have_an_initializer_1246", message: "An interface property cannot have an initializer." },
        A_type_literal_property_cannot_have_an_initializer: { code: 1247, category: ts.DiagnosticCategory.Error, key: "A_type_literal_property_cannot_have_an_initializer_1247", message: "A type literal property cannot have an initializer." },
        A_class_member_cannot_have_the_0_keyword: { code: 1248, category: ts.DiagnosticCategory.Error, key: "A_class_member_cannot_have_the_0_keyword_1248", message: "A class member cannot have the '{0}' keyword." },
        A_decorator_can_only_decorate_a_method_implementation_not_an_overload: { code: 1249, category: ts.DiagnosticCategory.Error, key: "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", message: "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: { code: 1250, category: ts.DiagnosticCategory.Error, key: "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", message: "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: { code: 1251, category: ts.DiagnosticCategory.Error, key: "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", message: "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: { code: 1252, category: ts.DiagnosticCategory.Error, key: "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", message: "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: { code: 1253, category: ts.DiagnosticCategory.Error, key: "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", message: "'{0}' tag cannot be used independently as a top level JSDoc tag." },
        with_statements_are_not_allowed_in_an_async_function_block: { code: 1300, category: ts.DiagnosticCategory.Error, key: "with_statements_are_not_allowed_in_an_async_function_block_1300", message: "'with' statements are not allowed in an async function block." },
        await_expression_is_only_allowed_within_an_async_function: { code: 1308, category: ts.DiagnosticCategory.Error, key: "await_expression_is_only_allowed_within_an_async_function_1308", message: "'await' expression is only allowed within an async function." },
        Async_functions_are_only_available_when_targeting_ECMAScript_2015_or_higher: { code: 1311, category: ts.DiagnosticCategory.Error, key: "Async_functions_are_only_available_when_targeting_ECMAScript_2015_or_higher_1311", message: "Async functions are only available when targeting ECMAScript 2015 or higher." },
        can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: { code: 1312, category: ts.DiagnosticCategory.Error, key: "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", message: "'=' can only be used in an object literal property inside a destructuring assignment." },
        The_body_of_an_if_statement_cannot_be_the_empty_statement: { code: 1313, category: ts.DiagnosticCategory.Error, key: "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", message: "The body of an 'if' statement cannot be the empty statement." },
        Global_module_exports_may_only_appear_in_module_files: { code: 1314, category: ts.DiagnosticCategory.Error, key: "Global_module_exports_may_only_appear_in_module_files_1314", message: "Global module exports may only appear in module files." },
        Global_module_exports_may_only_appear_in_declaration_files: { code: 1315, category: ts.DiagnosticCategory.Error, key: "Global_module_exports_may_only_appear_in_declaration_files_1315", message: "Global module exports may only appear in declaration files." },
        Global_module_exports_may_only_appear_at_top_level: { code: 1316, category: ts.DiagnosticCategory.Error, key: "Global_module_exports_may_only_appear_at_top_level_1316", message: "Global module exports may only appear at top level." },
        A_parameter_property_cannot_be_declared_using_a_rest_parameter: { code: 1317, category: ts.DiagnosticCategory.Error, key: "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", message: "A parameter property cannot be declared using a rest parameter." },
        Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_0_2300", message: "Duplicate identifier '{0}'." },
        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", message: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
        Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static_members_cannot_reference_class_type_parameters_2302", message: "Static members cannot reference class type parameters." },
        Circular_definition_of_import_alias_0: { code: 2303, category: ts.DiagnosticCategory.Error, key: "Circular_definition_of_import_alias_0_2303", message: "Circular definition of import alias '{0}'." },
        Cannot_find_name_0: { code: 2304, category: ts.DiagnosticCategory.Error, key: "Cannot_find_name_0_2304", message: "Cannot find name '{0}'." },
        Module_0_has_no_exported_member_1: { code: 2305, category: ts.DiagnosticCategory.Error, key: "Module_0_has_no_exported_member_1_2305", message: "Module '{0}' has no exported member '{1}'." },
        File_0_is_not_a_module: { code: 2306, category: ts.DiagnosticCategory.Error, key: "File_0_is_not_a_module_2306", message: "File '{0}' is not a module." },
        Cannot_find_module_0: { code: 2307, category: ts.DiagnosticCategory.Error, key: "Cannot_find_module_0_2307", message: "Cannot find module '{0}'." },
        Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: { code: 2308, category: ts.DiagnosticCategory.Error, key: "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", message: "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: { code: 2309, category: ts.DiagnosticCategory.Error, key: "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", message: "An export assignment cannot be used in a module with other exported elements." },
        Type_0_recursively_references_itself_as_a_base_type: { code: 2310, category: ts.DiagnosticCategory.Error, key: "Type_0_recursively_references_itself_as_a_base_type_2310", message: "Type '{0}' recursively references itself as a base type." },
        A_class_may_only_extend_another_class: { code: 2311, category: ts.DiagnosticCategory.Error, key: "A_class_may_only_extend_another_class_2311", message: "A class may only extend another class." },
        An_interface_may_only_extend_a_class_or_another_interface: { code: 2312, category: ts.DiagnosticCategory.Error, key: "An_interface_may_only_extend_a_class_or_another_interface_2312", message: "An interface may only extend a class or another interface." },
        Type_parameter_0_has_a_circular_constraint: { code: 2313, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_has_a_circular_constraint_2313", message: "Type parameter '{0}' has a circular constraint." },
        Generic_type_0_requires_1_type_argument_s: { code: 2314, category: ts.DiagnosticCategory.Error, key: "Generic_type_0_requires_1_type_argument_s_2314", message: "Generic type '{0}' requires {1} type argument(s)." },
        Type_0_is_not_generic: { code: 2315, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_generic_2315", message: "Type '{0}' is not generic." },
        Global_type_0_must_be_a_class_or_interface_type: { code: 2316, category: ts.DiagnosticCategory.Error, key: "Global_type_0_must_be_a_class_or_interface_type_2316", message: "Global type '{0}' must be a class or interface type." },
        Global_type_0_must_have_1_type_parameter_s: { code: 2317, category: ts.DiagnosticCategory.Error, key: "Global_type_0_must_have_1_type_parameter_s_2317", message: "Global type '{0}' must have {1} type parameter(s)." },
        Cannot_find_global_type_0: { code: 2318, category: ts.DiagnosticCategory.Error, key: "Cannot_find_global_type_0_2318", message: "Cannot find global type '{0}'." },
        Named_property_0_of_types_1_and_2_are_not_identical: { code: 2319, category: ts.DiagnosticCategory.Error, key: "Named_property_0_of_types_1_and_2_are_not_identical_2319", message: "Named property '{0}' of types '{1}' and '{2}' are not identical." },
        Interface_0_cannot_simultaneously_extend_types_1_and_2: { code: 2320, category: ts.DiagnosticCategory.Error, key: "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", message: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'." },
        Excessive_stack_depth_comparing_types_0_and_1: { code: 2321, category: ts.DiagnosticCategory.Error, key: "Excessive_stack_depth_comparing_types_0_and_1_2321", message: "Excessive stack depth comparing types '{0}' and '{1}'." },
        Type_0_is_not_assignable_to_type_1: { code: 2322, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_assignable_to_type_1_2322", message: "Type '{0}' is not assignable to type '{1}'." },
        Cannot_redeclare_exported_variable_0: { code: 2323, category: ts.DiagnosticCategory.Error, key: "Cannot_redeclare_exported_variable_0_2323", message: "Cannot redeclare exported variable '{0}'." },
        Property_0_is_missing_in_type_1: { code: 2324, category: ts.DiagnosticCategory.Error, key: "Property_0_is_missing_in_type_1_2324", message: "Property '{0}' is missing in type '{1}'." },
        Property_0_is_private_in_type_1_but_not_in_type_2: { code: 2325, category: ts.DiagnosticCategory.Error, key: "Property_0_is_private_in_type_1_but_not_in_type_2_2325", message: "Property '{0}' is private in type '{1}' but not in type '{2}'." },
        Types_of_property_0_are_incompatible: { code: 2326, category: ts.DiagnosticCategory.Error, key: "Types_of_property_0_are_incompatible_2326", message: "Types of property '{0}' are incompatible." },
        Property_0_is_optional_in_type_1_but_required_in_type_2: { code: 2327, category: ts.DiagnosticCategory.Error, key: "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", message: "Property '{0}' is optional in type '{1}' but required in type '{2}'." },
        Types_of_parameters_0_and_1_are_incompatible: { code: 2328, category: ts.DiagnosticCategory.Error, key: "Types_of_parameters_0_and_1_are_incompatible_2328", message: "Types of parameters '{0}' and '{1}' are incompatible." },
        Index_signature_is_missing_in_type_0: { code: 2329, category: ts.DiagnosticCategory.Error, key: "Index_signature_is_missing_in_type_0_2329", message: "Index signature is missing in type '{0}'." },
        Index_signatures_are_incompatible: { code: 2330, category: ts.DiagnosticCategory.Error, key: "Index_signatures_are_incompatible_2330", message: "Index signatures are incompatible." },
        this_cannot_be_referenced_in_a_module_or_namespace_body: { code: 2331, category: ts.DiagnosticCategory.Error, key: "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", message: "'this' cannot be referenced in a module or namespace body." },
        this_cannot_be_referenced_in_current_location: { code: 2332, category: ts.DiagnosticCategory.Error, key: "this_cannot_be_referenced_in_current_location_2332", message: "'this' cannot be referenced in current location." },
        this_cannot_be_referenced_in_constructor_arguments: { code: 2333, category: ts.DiagnosticCategory.Error, key: "this_cannot_be_referenced_in_constructor_arguments_2333", message: "'this' cannot be referenced in constructor arguments." },
        this_cannot_be_referenced_in_a_static_property_initializer: { code: 2334, category: ts.DiagnosticCategory.Error, key: "this_cannot_be_referenced_in_a_static_property_initializer_2334", message: "'this' cannot be referenced in a static property initializer." },
        super_can_only_be_referenced_in_a_derived_class: { code: 2335, category: ts.DiagnosticCategory.Error, key: "super_can_only_be_referenced_in_a_derived_class_2335", message: "'super' can only be referenced in a derived class." },
        super_cannot_be_referenced_in_constructor_arguments: { code: 2336, category: ts.DiagnosticCategory.Error, key: "super_cannot_be_referenced_in_constructor_arguments_2336", message: "'super' cannot be referenced in constructor arguments." },
        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: { code: 2337, category: ts.DiagnosticCategory.Error, key: "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", message: "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: { code: 2338, category: ts.DiagnosticCategory.Error, key: "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", message: "'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: { code: 2339, category: ts.DiagnosticCategory.Error, key: "Property_0_does_not_exist_on_type_1_2339", message: "Property '{0}' does not exist on type '{1}'." },
        Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: 2340, category: ts.DiagnosticCategory.Error, key: "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", message: "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: { code: 2341, category: ts.DiagnosticCategory.Error, key: "Property_0_is_private_and_only_accessible_within_class_1_2341", message: "Property '{0}' is private and only accessible within class '{1}'." },
        An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: { code: 2342, category: ts.DiagnosticCategory.Error, key: "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", message: "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'." },
        Type_0_does_not_satisfy_the_constraint_1: { code: 2344, category: ts.DiagnosticCategory.Error, key: "Type_0_does_not_satisfy_the_constraint_1_2344", message: "Type '{0}' does not satisfy the constraint '{1}'." },
        Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: { code: 2345, category: ts.DiagnosticCategory.Error, key: "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", message: "Argument of type '{0}' is not assignable to parameter of type '{1}'." },
        Supplied_parameters_do_not_match_any_signature_of_call_target: { code: 2346, category: ts.DiagnosticCategory.Error, key: "Supplied_parameters_do_not_match_any_signature_of_call_target_2346", message: "Supplied parameters do not match any signature of call target." },
        Untyped_function_calls_may_not_accept_type_arguments: { code: 2347, category: ts.DiagnosticCategory.Error, key: "Untyped_function_calls_may_not_accept_type_arguments_2347", message: "Untyped function calls may not accept type arguments." },
        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: { code: 2348, category: ts.DiagnosticCategory.Error, key: "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", message: "Value of type '{0}' is not callable. Did you mean to include 'new'?" },
        Cannot_invoke_an_expression_whose_type_lacks_a_call_signature: { code: 2349, category: ts.DiagnosticCategory.Error, key: "Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_2349", message: "Cannot invoke an expression whose type lacks a call signature." },
        Only_a_void_function_can_be_called_with_the_new_keyword: { code: 2350, category: ts.DiagnosticCategory.Error, key: "Only_a_void_function_can_be_called_with_the_new_keyword_2350", message: "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: { code: 2351, category: ts.DiagnosticCategory.Error, key: "Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature_2351", message: "Cannot use 'new' with an expression whose type lacks a call or construct signature." },
        Type_0_cannot_be_converted_to_type_1: { code: 2352, category: ts.DiagnosticCategory.Error, key: "Type_0_cannot_be_converted_to_type_1_2352", message: "Type '{0}' cannot be converted to type '{1}'." },
        Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: { code: 2353, category: ts.DiagnosticCategory.Error, key: "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", message: "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'." },
        No_best_common_type_exists_among_return_expressions: { code: 2354, category: ts.DiagnosticCategory.Error, key: "No_best_common_type_exists_among_return_expressions_2354", message: "No best common type exists among return expressions." },
        A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: { code: 2355, category: ts.DiagnosticCategory.Error, key: "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", message: "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: { code: 2356, category: ts.DiagnosticCategory.Error, key: "An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356", message: "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_property_or_indexer: { code: 2357, category: ts.DiagnosticCategory.Error, key: "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer_2357", message: "The operand of an increment or decrement operator must be a variable, property or indexer." },
        The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2358, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", message: "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: { code: 2359, category: ts.DiagnosticCategory.Error, key: "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", message: "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: { code: 2360, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", message: "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: { code: 2361, category: ts.DiagnosticCategory.Error, key: "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", message: "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: { code: 2362, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362", message: "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: { code: 2363, category: ts.DiagnosticCategory.Error, key: "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363", message: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
        Invalid_left_hand_side_of_assignment_expression: { code: 2364, category: ts.DiagnosticCategory.Error, key: "Invalid_left_hand_side_of_assignment_expression_2364", message: "Invalid left-hand side of assignment expression." },
        Operator_0_cannot_be_applied_to_types_1_and_2: { code: 2365, category: ts.DiagnosticCategory.Error, key: "Operator_0_cannot_be_applied_to_types_1_and_2_2365", message: "Operator '{0}' cannot be applied to types '{1}' and '{2}'." },
        Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: { code: 2366, category: ts.DiagnosticCategory.Error, key: "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", message: "Function lacks ending return statement and return type does not include 'undefined'." },
        Type_parameter_name_cannot_be_0: { code: 2368, category: ts.DiagnosticCategory.Error, key: "Type_parameter_name_cannot_be_0_2368", message: "Type parameter name cannot be '{0}'" },
        A_parameter_property_is_only_allowed_in_a_constructor_implementation: { code: 2369, category: ts.DiagnosticCategory.Error, key: "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", message: "A parameter property is only allowed in a constructor implementation." },
        A_rest_parameter_must_be_of_an_array_type: { code: 2370, category: ts.DiagnosticCategory.Error, key: "A_rest_parameter_must_be_of_an_array_type_2370", message: "A rest parameter must be of an array type." },
        A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: { code: 2371, category: ts.DiagnosticCategory.Error, key: "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", message: "A parameter initializer is only allowed in a function or constructor implementation." },
        Parameter_0_cannot_be_referenced_in_its_initializer: { code: 2372, category: ts.DiagnosticCategory.Error, key: "Parameter_0_cannot_be_referenced_in_its_initializer_2372", message: "Parameter '{0}' cannot be referenced in its initializer." },
        Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: { code: 2373, category: ts.DiagnosticCategory.Error, key: "Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it_2373", message: "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it." },
        Duplicate_string_index_signature: { code: 2374, category: ts.DiagnosticCategory.Error, key: "Duplicate_string_index_signature_2374", message: "Duplicate string index signature." },
        Duplicate_number_index_signature: { code: 2375, category: ts.DiagnosticCategory.Error, key: "Duplicate_number_index_signature_2375", message: "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: { code: 2376, category: ts.DiagnosticCategory.Error, key: "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", message: "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: { code: 2377, category: ts.DiagnosticCategory.Error, key: "Constructors_for_derived_classes_must_contain_a_super_call_2377", message: "Constructors for derived classes must contain a 'super' call." },
        A_get_accessor_must_return_a_value: { code: 2378, category: ts.DiagnosticCategory.Error, key: "A_get_accessor_must_return_a_value_2378", message: "A 'get' accessor must return a value." },
        Getter_and_setter_accessors_do_not_agree_in_visibility: { code: 2379, category: ts.DiagnosticCategory.Error, key: "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", message: "Getter and setter accessors do not agree in visibility." },
        get_and_set_accessor_must_have_the_same_type: { code: 2380, category: ts.DiagnosticCategory.Error, key: "get_and_set_accessor_must_have_the_same_type_2380", message: "'get' and 'set' accessor must have the same type." },
        A_signature_with_an_implementation_cannot_use_a_string_literal_type: { code: 2381, category: ts.DiagnosticCategory.Error, key: "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", message: "A signature with an implementation cannot use a string literal type." },
        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: { code: 2382, category: ts.DiagnosticCategory.Error, key: "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", message: "Specialized overload signature is not assignable to any non-specialized signature." },
        Overload_signatures_must_all_be_exported_or_non_exported: { code: 2383, category: ts.DiagnosticCategory.Error, key: "Overload_signatures_must_all_be_exported_or_non_exported_2383", message: "Overload signatures must all be exported or non-exported." },
        Overload_signatures_must_all_be_ambient_or_non_ambient: { code: 2384, category: ts.DiagnosticCategory.Error, key: "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", message: "Overload signatures must all be ambient or non-ambient." },
        Overload_signatures_must_all_be_public_private_or_protected: { code: 2385, category: ts.DiagnosticCategory.Error, key: "Overload_signatures_must_all_be_public_private_or_protected_2385", message: "Overload signatures must all be public, private or protected." },
        Overload_signatures_must_all_be_optional_or_required: { code: 2386, category: ts.DiagnosticCategory.Error, key: "Overload_signatures_must_all_be_optional_or_required_2386", message: "Overload signatures must all be optional or required." },
        Function_overload_must_be_static: { code: 2387, category: ts.DiagnosticCategory.Error, key: "Function_overload_must_be_static_2387", message: "Function overload must be static." },
        Function_overload_must_not_be_static: { code: 2388, category: ts.DiagnosticCategory.Error, key: "Function_overload_must_not_be_static_2388", message: "Function overload must not be static." },
        Function_implementation_name_must_be_0: { code: 2389, category: ts.DiagnosticCategory.Error, key: "Function_implementation_name_must_be_0_2389", message: "Function implementation name must be '{0}'." },
        Constructor_implementation_is_missing: { code: 2390, category: ts.DiagnosticCategory.Error, key: "Constructor_implementation_is_missing_2390", message: "Constructor implementation is missing." },
        Function_implementation_is_missing_or_not_immediately_following_the_declaration: { code: 2391, category: ts.DiagnosticCategory.Error, key: "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", message: "Function implementation is missing or not immediately following the declaration." },
        Multiple_constructor_implementations_are_not_allowed: { code: 2392, category: ts.DiagnosticCategory.Error, key: "Multiple_constructor_implementations_are_not_allowed_2392", message: "Multiple constructor implementations are not allowed." },
        Duplicate_function_implementation: { code: 2393, category: ts.DiagnosticCategory.Error, key: "Duplicate_function_implementation_2393", message: "Duplicate function implementation." },
        Overload_signature_is_not_compatible_with_function_implementation: { code: 2394, category: ts.DiagnosticCategory.Error, key: "Overload_signature_is_not_compatible_with_function_implementation_2394", message: "Overload signature is not compatible with function implementation." },
        Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: ts.DiagnosticCategory.Error, key: "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", message: "Individual declarations in merged declaration '{0}' must be all exported or all local." },
        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2396, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", message: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." },
        Declaration_name_conflicts_with_built_in_global_identifier_0: { code: 2397, category: ts.DiagnosticCategory.Error, key: "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", message: "Declaration name conflicts with built-in global identifier '{0}'." },
        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: { code: 2399, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", message: "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: { code: 2400, category: ts.DiagnosticCategory.Error, key: "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", message: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference." },
        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: { code: 2401, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", message: "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference." },
        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: { code: 2402, category: ts.DiagnosticCategory.Error, key: "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", message: "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: { code: 2403, category: ts.DiagnosticCategory.Error, key: "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", message: "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: { code: 2404, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", message: "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: { code: 2405, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", message: "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'." },
        Invalid_left_hand_side_in_for_in_statement: { code: 2406, category: ts.DiagnosticCategory.Error, key: "Invalid_left_hand_side_in_for_in_statement_2406", message: "Invalid left-hand side in 'for...in' statement." },
        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2407, category: ts.DiagnosticCategory.Error, key: "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_2407", message: "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: { code: 2408, category: ts.DiagnosticCategory.Error, key: "Setters_cannot_return_a_value_2408", message: "Setters cannot return a value." },
        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: { code: 2409, category: ts.DiagnosticCategory.Error, key: "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", message: "Return type of constructor signature must be assignable to the instance type of the class" },
        All_symbols_within_a_with_block_will_be_resolved_to_any: { code: 2410, category: ts.DiagnosticCategory.Error, key: "All_symbols_within_a_with_block_will_be_resolved_to_any_2410", message: "All symbols within a 'with' block will be resolved to 'any'." },
        Property_0_of_type_1_is_not_assignable_to_string_index_type_2: { code: 2411, category: ts.DiagnosticCategory.Error, key: "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", message: "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: { code: 2412, category: ts.DiagnosticCategory.Error, key: "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", message: "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: { code: 2413, category: ts.DiagnosticCategory.Error, key: "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", message: "Numeric index type '{0}' is not assignable to string index type '{1}'." },
        Class_name_cannot_be_0: { code: 2414, category: ts.DiagnosticCategory.Error, key: "Class_name_cannot_be_0_2414", message: "Class name cannot be '{0}'" },
        Class_0_incorrectly_extends_base_class_1: { code: 2415, category: ts.DiagnosticCategory.Error, key: "Class_0_incorrectly_extends_base_class_1_2415", message: "Class '{0}' incorrectly extends base class '{1}'." },
        Class_static_side_0_incorrectly_extends_base_class_static_side_1: { code: 2417, category: ts.DiagnosticCategory.Error, key: "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", message: "Class static side '{0}' incorrectly extends base class static side '{1}'." },
        Class_0_incorrectly_implements_interface_1: { code: 2420, category: ts.DiagnosticCategory.Error, key: "Class_0_incorrectly_implements_interface_1_2420", message: "Class '{0}' incorrectly implements interface '{1}'." },
        A_class_may_only_implement_another_class_or_interface: { code: 2422, category: ts.DiagnosticCategory.Error, key: "A_class_may_only_implement_another_class_or_interface_2422", message: "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: { code: 2423, category: ts.DiagnosticCategory.Error, key: "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", message: "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: { code: 2424, category: ts.DiagnosticCategory.Error, key: "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_proper_2424", message: "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: { code: 2425, category: ts.DiagnosticCategory.Error, key: "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", message: "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: { code: 2426, category: ts.DiagnosticCategory.Error, key: "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", message: "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function." },
        Interface_name_cannot_be_0: { code: 2427, category: ts.DiagnosticCategory.Error, key: "Interface_name_cannot_be_0_2427", message: "Interface name cannot be '{0}'" },
        All_declarations_of_0_must_have_identical_type_parameters: { code: 2428, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_type_parameters_2428", message: "All declarations of '{0}' must have identical type parameters." },
        Interface_0_incorrectly_extends_interface_1: { code: 2430, category: ts.DiagnosticCategory.Error, key: "Interface_0_incorrectly_extends_interface_1_2430", message: "Interface '{0}' incorrectly extends interface '{1}'." },
        Enum_name_cannot_be_0: { code: 2431, category: ts.DiagnosticCategory.Error, key: "Enum_name_cannot_be_0_2431", message: "Enum name cannot be '{0}'" },
        In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: { code: 2432, category: ts.DiagnosticCategory.Error, key: "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", message: "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: { code: 2433, category: ts.DiagnosticCategory.Error, key: "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", message: "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: { code: 2434, category: ts.DiagnosticCategory.Error, key: "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", message: "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: { code: 2435, category: ts.DiagnosticCategory.Error, key: "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", message: "Ambient modules cannot be nested in other modules or namespaces." },
        Ambient_module_declaration_cannot_specify_relative_module_name: { code: 2436, category: ts.DiagnosticCategory.Error, key: "Ambient_module_declaration_cannot_specify_relative_module_name_2436", message: "Ambient module declaration cannot specify relative module name." },
        Module_0_is_hidden_by_a_local_declaration_with_the_same_name: { code: 2437, category: ts.DiagnosticCategory.Error, key: "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", message: "Module '{0}' is hidden by a local declaration with the same name" },
        Import_name_cannot_be_0: { code: 2438, category: ts.DiagnosticCategory.Error, key: "Import_name_cannot_be_0_2438", message: "Import name cannot be '{0}'" },
        Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: { code: 2439, category: ts.DiagnosticCategory.Error, key: "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", message: "Import or export declaration in an ambient module declaration cannot reference module through relative module name." },
        Import_declaration_conflicts_with_local_declaration_of_0: { code: 2440, category: ts.DiagnosticCategory.Error, key: "Import_declaration_conflicts_with_local_declaration_of_0_2440", message: "Import declaration conflicts with local declaration of '{0}'" },
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: { code: 2441, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", message: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module." },
        Types_have_separate_declarations_of_a_private_property_0: { code: 2442, category: ts.DiagnosticCategory.Error, key: "Types_have_separate_declarations_of_a_private_property_0_2442", message: "Types have separate declarations of a private property '{0}'." },
        Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: { code: 2443, category: ts.DiagnosticCategory.Error, key: "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", message: "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: { code: 2444, category: ts.DiagnosticCategory.Error, key: "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", message: "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: { code: 2445, category: ts.DiagnosticCategory.Error, key: "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", message: "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: { code: 2446, category: ts.DiagnosticCategory.Error, key: "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", message: "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: { code: 2447, category: ts.DiagnosticCategory.Error, key: "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", message: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." },
        Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: ts.DiagnosticCategory.Error, key: "Block_scoped_variable_0_used_before_its_declaration_2448", message: "Block-scoped variable '{0}' used before its declaration." },
        The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant_or_a_read_only_property: { code: 2449, category: ts.DiagnosticCategory.Error, key: "The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant_or_a_read_only_property_2449", message: "The operand of an increment or decrement operator cannot be a constant or a read-only property." },
        Left_hand_side_of_assignment_expression_cannot_be_a_constant_or_a_read_only_property: { code: 2450, category: ts.DiagnosticCategory.Error, key: "Left_hand_side_of_assignment_expression_cannot_be_a_constant_or_a_read_only_property_2450", message: "Left-hand side of assignment expression cannot be a constant or a read-only property." },
        Cannot_redeclare_block_scoped_variable_0: { code: 2451, category: ts.DiagnosticCategory.Error, key: "Cannot_redeclare_block_scoped_variable_0_2451", message: "Cannot redeclare block-scoped variable '{0}'." },
        An_enum_member_cannot_have_a_numeric_name: { code: 2452, category: ts.DiagnosticCategory.Error, key: "An_enum_member_cannot_have_a_numeric_name_2452", message: "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: { code: 2453, category: ts.DiagnosticCategory.Error, key: "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", message: "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: { code: 2454, category: ts.DiagnosticCategory.Error, key: "Variable_0_is_used_before_being_assigned_2454", message: "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: { code: 2455, category: ts.DiagnosticCategory.Error, key: "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", message: "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: { code: 2456, category: ts.DiagnosticCategory.Error, key: "Type_alias_0_circularly_references_itself_2456", message: "Type alias '{0}' circularly references itself." },
        Type_alias_name_cannot_be_0: { code: 2457, category: ts.DiagnosticCategory.Error, key: "Type_alias_name_cannot_be_0_2457", message: "Type alias name cannot be '{0}'" },
        An_AMD_module_cannot_have_multiple_name_assignments: { code: 2458, category: ts.DiagnosticCategory.Error, key: "An_AMD_module_cannot_have_multiple_name_assignments_2458", message: "An AMD module cannot have multiple name assignments." },
        Type_0_has_no_property_1_and_no_string_index_signature: { code: 2459, category: ts.DiagnosticCategory.Error, key: "Type_0_has_no_property_1_and_no_string_index_signature_2459", message: "Type '{0}' has no property '{1}' and no string index signature." },
        Type_0_has_no_property_1: { code: 2460, category: ts.DiagnosticCategory.Error, key: "Type_0_has_no_property_1_2460", message: "Type '{0}' has no property '{1}'." },
        Type_0_is_not_an_array_type: { code: 2461, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_an_array_type_2461", message: "Type '{0}' is not an array type." },
        A_rest_element_must_be_last_in_an_array_destructuring_pattern: { code: 2462, category: ts.DiagnosticCategory.Error, key: "A_rest_element_must_be_last_in_an_array_destructuring_pattern_2462", message: "A rest element must be last in an array destructuring pattern" },
        A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: { code: 2463, category: ts.DiagnosticCategory.Error, key: "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", message: "A binding pattern parameter cannot be optional in an implementation signature." },
        A_computed_property_name_must_be_of_type_string_number_symbol_or_any: { code: 2464, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", message: "A computed property name must be of type 'string', 'number', 'symbol', or 'any'." },
        this_cannot_be_referenced_in_a_computed_property_name: { code: 2465, category: ts.DiagnosticCategory.Error, key: "this_cannot_be_referenced_in_a_computed_property_name_2465", message: "'this' cannot be referenced in a computed property name." },
        super_cannot_be_referenced_in_a_computed_property_name: { code: 2466, category: ts.DiagnosticCategory.Error, key: "super_cannot_be_referenced_in_a_computed_property_name_2466", message: "'super' cannot be referenced in a computed property name." },
        A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: { code: 2467, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", message: "A computed property name cannot reference a type parameter from its containing type." },
        Cannot_find_global_value_0: { code: 2468, category: ts.DiagnosticCategory.Error, key: "Cannot_find_global_value_0_2468", message: "Cannot find global value '{0}'." },
        The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: ts.DiagnosticCategory.Error, key: "The_0_operator_cannot_be_applied_to_type_symbol_2469", message: "The '{0}' operator cannot be applied to type 'symbol'." },
        Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: ts.DiagnosticCategory.Error, key: "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", message: "'Symbol' reference does not refer to the global Symbol constructor object." },
        A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: ts.DiagnosticCategory.Error, key: "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", message: "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: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", message: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." },
        Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: ts.DiagnosticCategory.Error, key: "Enum_declarations_must_all_be_const_or_non_const_2473", message: "Enum declarations must all be const or non-const." },
        In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: ts.DiagnosticCategory.Error, key: "In_const_enum_declarations_member_initializer_must_be_constant_expression_2474", message: "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: { code: 2475, category: ts.DiagnosticCategory.Error, key: "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", message: "'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: { code: 2476, category: ts.DiagnosticCategory.Error, key: "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", message: "A const enum member can only be accessed using a string literal." },
        const_enum_member_initializer_was_evaluated_to_a_non_finite_value: { code: 2477, category: ts.DiagnosticCategory.Error, key: "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", message: "'const' enum member initializer was evaluated to a non-finite value." },
        const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 2478, category: ts.DiagnosticCategory.Error, key: "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", message: "'const' enum member initializer was evaluated to disallowed value 'NaN'." },
        Property_0_does_not_exist_on_const_enum_1: { code: 2479, category: ts.DiagnosticCategory.Error, key: "Property_0_does_not_exist_on_const_enum_1_2479", message: "Property '{0}' does not exist on 'const' enum '{1}'." },
        let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 2480, category: ts.DiagnosticCategory.Error, key: "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", message: "'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: { code: 2481, category: ts.DiagnosticCategory.Error, key: "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", message: "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: { code: 2483, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", message: "The left-hand side of a 'for...of' statement cannot use a type annotation." },
        Export_declaration_conflicts_with_exported_declaration_of_0: { code: 2484, category: ts.DiagnosticCategory.Error, key: "Export_declaration_conflicts_with_exported_declaration_of_0_2484", message: "Export declaration conflicts with exported declaration of '{0}'" },
        The_left_hand_side_of_a_for_of_statement_cannot_be_a_constant_or_a_read_only_property: { code: 2485, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_of_statement_cannot_be_a_constant_or_a_read_only_property_2485", message: "The left-hand side of a 'for...of' statement cannot be a constant or a read-only property." },
        The_left_hand_side_of_a_for_in_statement_cannot_be_a_constant_or_a_read_only_property: { code: 2486, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_in_statement_cannot_be_a_constant_or_a_read_only_property_2486", message: "The left-hand side of a 'for...in' statement cannot be a constant or a read-only property." },
        Invalid_left_hand_side_in_for_of_statement: { code: 2487, category: ts.DiagnosticCategory.Error, key: "Invalid_left_hand_side_in_for_of_statement_2487", message: "Invalid left-hand side in 'for...of' statement." },
        Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator: { code: 2488, category: ts.DiagnosticCategory.Error, key: "Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", message: "Type must have a '[Symbol.iterator]()' method that returns an iterator." },
        An_iterator_must_have_a_next_method: { code: 2489, category: ts.DiagnosticCategory.Error, key: "An_iterator_must_have_a_next_method_2489", message: "An iterator must have a 'next()' method." },
        The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property: { code: 2490, category: ts.DiagnosticCategory.Error, key: "The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property_2490", message: "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: { code: 2491, category: ts.DiagnosticCategory.Error, key: "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", message: "The left-hand side of a 'for...in' statement cannot be a destructuring pattern." },
        Cannot_redeclare_identifier_0_in_catch_clause: { code: 2492, category: ts.DiagnosticCategory.Error, key: "Cannot_redeclare_identifier_0_in_catch_clause_2492", message: "Cannot redeclare identifier '{0}' in catch clause" },
        Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2: { code: 2493, category: ts.DiagnosticCategory.Error, key: "Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2_2493", message: "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: { code: 2494, category: ts.DiagnosticCategory.Error, key: "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", message: "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: { code: 2495, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_an_array_type_or_a_string_type_2495", message: "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: { code: 2496, category: ts.DiagnosticCategory.Error, key: "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", message: "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: { code: 2497, category: ts.DiagnosticCategory.Error, key: "Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497", message: "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: { code: 2498, category: ts.DiagnosticCategory.Error, key: "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", message: "Module '{0}' uses 'export =' and cannot be used with 'export *'." },
        An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: { code: 2499, category: ts.DiagnosticCategory.Error, key: "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", message: "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: { code: 2500, category: ts.DiagnosticCategory.Error, key: "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", message: "A class can only implement an identifier/qualified-name with optional type arguments." },
        A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: ts.DiagnosticCategory.Error, key: "A_rest_element_cannot_contain_a_binding_pattern_2501", message: "A rest element cannot contain a binding pattern." },
        _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: ts.DiagnosticCategory.Error, key: "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", message: "'{0}' is referenced directly or indirectly in its own type annotation." },
        Cannot_find_namespace_0: { code: 2503, category: ts.DiagnosticCategory.Error, key: "Cannot_find_namespace_0_2503", message: "Cannot find namespace '{0}'." },
        No_best_common_type_exists_among_yield_expressions: { code: 2504, category: ts.DiagnosticCategory.Error, key: "No_best_common_type_exists_among_yield_expressions_2504", message: "No best common type exists among yield expressions." },
        A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: ts.DiagnosticCategory.Error, key: "A_generator_cannot_have_a_void_type_annotation_2505", message: "A generator cannot have a 'void' type annotation." },
        _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: { code: 2506, category: ts.DiagnosticCategory.Error, key: "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", message: "'{0}' is referenced directly or indirectly in its own base expression." },
        Type_0_is_not_a_constructor_function_type: { code: 2507, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_a_constructor_function_type_2507", message: "Type '{0}' is not a constructor function type." },
        No_base_constructor_has_the_specified_number_of_type_arguments: { code: 2508, category: ts.DiagnosticCategory.Error, key: "No_base_constructor_has_the_specified_number_of_type_arguments_2508", message: "No base constructor has the specified number of type arguments." },
        Base_constructor_return_type_0_is_not_a_class_or_interface_type: { code: 2509, category: ts.DiagnosticCategory.Error, key: "Base_constructor_return_type_0_is_not_a_class_or_interface_type_2509", message: "Base constructor return type '{0}' is not a class or interface type." },
        Base_constructors_must_all_have_the_same_return_type: { code: 2510, category: ts.DiagnosticCategory.Error, key: "Base_constructors_must_all_have_the_same_return_type_2510", message: "Base constructors must all have the same return type." },
        Cannot_create_an_instance_of_the_abstract_class_0: { code: 2511, category: ts.DiagnosticCategory.Error, key: "Cannot_create_an_instance_of_the_abstract_class_0_2511", message: "Cannot create an instance of the abstract class '{0}'." },
        Overload_signatures_must_all_be_abstract_or_non_abstract: { code: 2512, category: ts.DiagnosticCategory.Error, key: "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", message: "Overload signatures must all be abstract or non-abstract." },
        Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: { code: 2513, category: ts.DiagnosticCategory.Error, key: "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", message: "Abstract method '{0}' in class '{1}' cannot be accessed via super expression." },
        Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: ts.DiagnosticCategory.Error, key: "Classes_containing_abstract_methods_must_be_marked_abstract_2514", message: "Classes containing abstract methods must be marked abstract." },
        Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: ts.DiagnosticCategory.Error, key: "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", message: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." },
        All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_an_abstract_method_must_be_consecutive_2516", message: "All declarations of an abstract method must be consecutive." },
        Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", message: "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: { code: 2518, category: ts.DiagnosticCategory.Error, key: "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", message: "A 'this'-based type guard is not compatible with a parameter-based type guard." },
        Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", message: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." },
        Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: ts.DiagnosticCategory.Error, key: "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", message: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." },
        The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_function_expression: { code: 2522, category: ts.DiagnosticCategory.Error, key: "The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_2522", message: "The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression." },
        yield_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2523, category: ts.DiagnosticCategory.Error, key: "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", message: "'yield' expressions cannot be used in a parameter initializer." },
        await_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2524, category: ts.DiagnosticCategory.Error, key: "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", message: "'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: { code: 2525, category: ts.DiagnosticCategory.Error, key: "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", message: "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: { code: 2526, category: ts.DiagnosticCategory.Error, key: "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", message: "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: { code: 2527, category: ts.DiagnosticCategory.Error, key: "The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary_2527", message: "The inferred type of '{0}' references an inaccessible 'this' type. A type annotation is necessary." },
        A_module_cannot_have_multiple_default_exports: { code: 2528, category: ts.DiagnosticCategory.Error, key: "A_module_cannot_have_multiple_default_exports_2528", message: "A module cannot have multiple default exports." },
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: { code: 2529, category: ts.DiagnosticCategory.Error, key: "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", message: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions." },
        Property_0_is_incompatible_with_index_signature: { code: 2530, category: ts.DiagnosticCategory.Error, key: "Property_0_is_incompatible_with_index_signature_2530", message: "Property '{0}' is incompatible with index signature." },
        Object_is_possibly_null: { code: 2531, category: ts.DiagnosticCategory.Error, key: "Object_is_possibly_null_2531", message: "Object is possibly 'null'." },
        Object_is_possibly_undefined: { code: 2532, category: ts.DiagnosticCategory.Error, key: "Object_is_possibly_undefined_2532", message: "Object is possibly 'undefined'." },
        Object_is_possibly_null_or_undefined: { code: 2533, category: ts.DiagnosticCategory.Error, key: "Object_is_possibly_null_or_undefined_2533", message: "Object is possibly 'null' or 'undefined'." },
        A_function_returning_never_cannot_have_a_reachable_end_point: { code: 2534, category: ts.DiagnosticCategory.Error, key: "A_function_returning_never_cannot_have_a_reachable_end_point_2534", message: "A function returning 'never' cannot have a reachable end point." },
        JSX_element_attributes_type_0_may_not_be_a_union_type: { code: 2600, category: ts.DiagnosticCategory.Error, key: "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", message: "JSX element attributes type '{0}' may not be a union type." },
        The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: { code: 2601, category: ts.DiagnosticCategory.Error, key: "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", message: "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: { code: 2602, category: ts.DiagnosticCategory.Error, key: "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", message: "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: { code: 2603, category: ts.DiagnosticCategory.Error, key: "Property_0_in_type_1_is_not_assignable_to_type_2_2603", message: "Property '{0}' in type '{1}' is not assignable to type '{2}'" },
        JSX_element_type_0_does_not_have_any_construct_or_call_signatures: { code: 2604, category: ts.DiagnosticCategory.Error, key: "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", message: "JSX element type '{0}' does not have any construct or call signatures." },
        JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: { code: 2605, category: ts.DiagnosticCategory.Error, key: "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", message: "JSX element type '{0}' is not a constructor function for JSX elements." },
        Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: { code: 2606, category: ts.DiagnosticCategory.Error, key: "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", message: "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: { code: 2607, category: ts.DiagnosticCategory.Error, key: "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", message: "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: { code: 2608, category: ts.DiagnosticCategory.Error, key: "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", message: "The global type 'JSX.{0}' may not have more than one property" },
        Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: ts.DiagnosticCategory.Error, key: "Cannot_emit_namespaced_JSX_elements_in_React_2650", message: "Cannot emit namespaced JSX elements in React" },
        A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: ts.DiagnosticCategory.Error, key: "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", message: "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: { code: 2652, category: ts.DiagnosticCategory.Error, key: "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", message: "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: { code: 2653, category: ts.DiagnosticCategory.Error, key: "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", message: "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: { code: 2654, category: ts.DiagnosticCategory.Error, key: "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", message: "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: { code: 2656, category: ts.DiagnosticCategory.Error, key: "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", message: "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: { code: 2657, category: ts.DiagnosticCategory.Error, key: "JSX_expressions_must_have_one_parent_element_2657", message: "JSX expressions must have one parent element" },
        Type_0_provides_no_match_for_the_signature_1: { code: 2658, category: ts.DiagnosticCategory.Error, key: "Type_0_provides_no_match_for_the_signature_1_2658", message: "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: { code: 2659, category: ts.DiagnosticCategory.Error, key: "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", message: "'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: { code: 2660, category: ts.DiagnosticCategory.Error, key: "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", message: "'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: { code: 2661, category: ts.DiagnosticCategory.Error, key: "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", message: "Cannot export '{0}'. Only local declarations can be exported from a module." },
        Cannot_find_name_0_Did_you_mean_the_static_member_1_0: { code: 2662, category: ts.DiagnosticCategory.Error, key: "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", message: "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?" },
        Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: { code: 2663, category: ts.DiagnosticCategory.Error, key: "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", message: "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?" },
        Invalid_module_name_in_augmentation_module_0_cannot_be_found: { code: 2664, category: ts.DiagnosticCategory.Error, key: "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", message: "Invalid module name in augmentation, module '{0}' cannot be found." },
        Exports_and_export_assignments_are_not_permitted_in_module_augmentations: { code: 2666, category: ts.DiagnosticCategory.Error, key: "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", message: "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: { code: 2667, category: ts.DiagnosticCategory.Error, key: "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", message: "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: { code: 2668, category: ts.DiagnosticCategory.Error, key: "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", message: "'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: { code: 2669, category: ts.DiagnosticCategory.Error, key: "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", message: "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: { code: 2670, category: ts.DiagnosticCategory.Error, key: "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", message: "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: { code: 2671, category: ts.DiagnosticCategory.Error, key: "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", message: "Cannot augment module '{0}' because it resolves to a non-module entity." },
        Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: { code: 2672, category: ts.DiagnosticCategory.Error, key: "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", message: "Cannot assign a '{0}' constructor type to a '{1}' constructor type." },
        Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: { code: 2673, category: ts.DiagnosticCategory.Error, key: "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", message: "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: { code: 2674, category: ts.DiagnosticCategory.Error, key: "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", message: "Constructor of class '{0}' is protected and only accessible within the class declaration." },
        Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: { code: 2675, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", message: "Cannot extend a class '{0}'. Class constructor is marked as private." },
        Accessors_must_both_be_abstract_or_non_abstract: { code: 2676, category: ts.DiagnosticCategory.Error, key: "Accessors_must_both_be_abstract_or_non_abstract_2676", message: "Accessors must both be abstract or non-abstract." },
        A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: { code: 2677, category: ts.DiagnosticCategory.Error, key: "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", message: "A type predicate's type must be assignable to its parameter's type." },
        Type_0_is_not_comparable_to_type_1: { code: 2678, category: ts.DiagnosticCategory.Error, key: "Type_0_is_not_comparable_to_type_1_2678", message: "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: { code: 2679, category: ts.DiagnosticCategory.Error, key: "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", message: "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'." },
        A_this_parameter_must_be_the_first_parameter: { code: 2680, category: ts.DiagnosticCategory.Error, key: "A_this_parameter_must_be_the_first_parameter_2680", message: "A 'this' parameter must be the first parameter." },
        A_constructor_cannot_have_a_this_parameter: { code: 2681, category: ts.DiagnosticCategory.Error, key: "A_constructor_cannot_have_a_this_parameter_2681", message: "A constructor cannot have a 'this' parameter." },
        get_and_set_accessor_must_have_the_same_this_type: { code: 2682, category: ts.DiagnosticCategory.Error, key: "get_and_set_accessor_must_have_the_same_this_type_2682", message: "'get' and 'set' accessor must have the same 'this' type." },
        this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: { code: 2683, category: ts.DiagnosticCategory.Error, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", message: "'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: { code: 2684, category: ts.DiagnosticCategory.Error, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", message: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'." },
        The_this_types_of_each_signature_are_incompatible: { code: 2685, category: ts.DiagnosticCategory.Error, key: "The_this_types_of_each_signature_are_incompatible_2685", message: "The 'this' types of each signature are incompatible." },
        Identifier_0_must_be_imported_from_a_module: { code: 2686, category: ts.DiagnosticCategory.Error, key: "Identifier_0_must_be_imported_from_a_module_2686", message: "Identifier '{0}' must be imported from a module" },
        All_declarations_of_0_must_have_identical_modifiers: { code: 2687, category: ts.DiagnosticCategory.Error, key: "All_declarations_of_0_must_have_identical_modifiers_2687", message: "All declarations of '{0}' must have identical modifiers." },
        Cannot_find_type_definition_file_for_0: { code: 2688, category: ts.DiagnosticCategory.Error, key: "Cannot_find_type_definition_file_for_0_2688", message: "Cannot find type definition file for '{0}'." },
        Cannot_extend_an_interface_0_Did_you_mean_implements: { code: 2689, category: ts.DiagnosticCategory.Error, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", message: "Cannot extend an interface '{0}'. Did you mean 'implements'?" },
        Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import_declaration_0_is_using_private_name_1_4000", message: "Import declaration '{0}' is using private name '{1}'." },
        Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", message: "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: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", message: "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: { code: 4006, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", message: "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: { code: 4008, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", message: "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: { code: 4010, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", message: "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: { code: 4012, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", message: "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: { code: 4014, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", message: "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: { code: 4016, category: ts.DiagnosticCategory.Error, key: "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", message: "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: { code: 4019, category: ts.DiagnosticCategory.Error, key: "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", message: "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: { code: 4020, category: ts.DiagnosticCategory.Error, key: "Extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", message: "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: { code: 4022, category: ts.DiagnosticCategory.Error, key: "Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", message: "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: { code: 4023, category: ts.DiagnosticCategory.Error, key: "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", message: "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: { code: 4024, category: ts.DiagnosticCategory.Error, key: "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", message: "Exported variable '{0}' has or is using name '{1}' from private module '{2}'." },
        Exported_variable_0_has_or_is_using_private_name_1: { code: 4025, category: ts.DiagnosticCategory.Error, key: "Exported_variable_0_has_or_is_using_private_name_1_4025", message: "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: { code: 4026, category: ts.DiagnosticCategory.Error, key: "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", message: "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: { code: 4027, category: ts.DiagnosticCategory.Error, key: "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", message: "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: { code: 4028, category: ts.DiagnosticCategory.Error, key: "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", message: "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: { code: 4029, category: ts.DiagnosticCategory.Error, key: "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", message: "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: { code: 4030, category: ts.DiagnosticCategory.Error, key: "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", message: "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: { code: 4031, category: ts.DiagnosticCategory.Error, key: "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", message: "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: { code: 4032, category: ts.DiagnosticCategory.Error, key: "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", message: "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: { code: 4033, category: ts.DiagnosticCategory.Error, key: "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", message: "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: { code: 4034, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_4034", message: "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: { code: 4035, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1_4035", message: "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: { code: 4036, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_4036", message: "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: { code: 4037, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1_4037", message: "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: { code: 4038, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_externa_4038", message: "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: { code: 4039, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_4039", message: "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: { code: 4040, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0_4040", message: "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: { code: 4041, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_modul_4041", message: "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: { code: 4042, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_4042", message: "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: { code: 4043, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0_4043", message: "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: { code: 4044, category: ts.DiagnosticCategory.Error, key: "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", message: "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: { code: 4045, category: ts.DiagnosticCategory.Error, key: "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", message: "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: { code: 4046, category: ts.DiagnosticCategory.Error, key: "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", message: "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: { code: 4047, category: ts.DiagnosticCategory.Error, key: "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", message: "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: { code: 4048, category: ts.DiagnosticCategory.Error, key: "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", message: "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: { code: 4049, category: ts.DiagnosticCategory.Error, key: "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", message: "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: { code: 4050, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", message: "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: { code: 4051, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", message: "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: { code: 4052, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", message: "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: { code: 4053, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", message: "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: { code: 4054, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", message: "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: { code: 4055, category: ts.DiagnosticCategory.Error, key: "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", message: "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: { code: 4056, category: ts.DiagnosticCategory.Error, key: "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", message: "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: { code: 4057, category: ts.DiagnosticCategory.Error, key: "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", message: "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: { code: 4058, category: ts.DiagnosticCategory.Error, key: "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", message: "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: { code: 4059, category: ts.DiagnosticCategory.Error, key: "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", message: "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: { code: 4060, category: ts.DiagnosticCategory.Error, key: "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", message: "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: { code: 4061, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", message: "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: { code: 4062, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", message: "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: { code: 4063, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", message: "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: { code: 4064, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", message: "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: { code: 4065, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", message: "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: { code: 4066, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", message: "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: { code: 4067, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", message: "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: { code: 4068, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", message: "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: { code: 4069, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", message: "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: { code: 4070, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", message: "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: { code: 4071, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", message: "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: { code: 4072, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", message: "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: { code: 4073, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", message: "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: { code: 4074, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", message: "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: { code: 4075, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", message: "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: { code: 4076, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", message: "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: { code: 4077, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", message: "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: { code: 4078, category: ts.DiagnosticCategory.Error, key: "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", message: "Parameter '{0}' of exported function has or is using private name '{1}'." },
        Exported_type_alias_0_has_or_is_using_private_name_1: { code: 4081, category: ts.DiagnosticCategory.Error, key: "Exported_type_alias_0_has_or_is_using_private_name_1_4081", message: "Exported type alias '{0}' has or is using private name '{1}'." },
        Default_export_of_the_module_has_or_is_using_private_name_0: { code: 4082, category: ts.DiagnosticCategory.Error, key: "Default_export_of_the_module_has_or_is_using_private_name_0_4082", message: "Default export of the module has or is using private name '{0}'." },
        Conflicting_library_definitions_for_0_found_at_1_and_2_Copy_the_correct_file_to_the_typings_folder_to_resolve_this_conflict: { code: 4090, category: ts.DiagnosticCategory.Message, key: "Conflicting_library_definitions_for_0_found_at_1_and_2_Copy_the_correct_file_to_the_typings_folder_t_4090", message: "Conflicting library definitions for '{0}' found at '{1}' and '{2}'. Copy the correct file to the 'typings' folder to resolve this conflict." },
        The_current_host_does_not_support_the_0_option: { code: 5001, category: ts.DiagnosticCategory.Error, key: "The_current_host_does_not_support_the_0_option_5001", message: "The current host does not support the '{0}' option." },
        Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: ts.DiagnosticCategory.Error, key: "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", message: "Cannot find the common subdirectory path for the input files." },
        File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: { code: 5010, category: ts.DiagnosticCategory.Error, key: "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", message: "File specification cannot end in a recursive directory wildcard ('**'): '{0}'." },
        File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0: { code: 5011, category: ts.DiagnosticCategory.Error, key: "File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0_5011", message: "File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'." },
        Cannot_read_file_0_Colon_1: { code: 5012, category: ts.DiagnosticCategory.Error, key: "Cannot_read_file_0_Colon_1_5012", message: "Cannot read file '{0}': {1}" },
        Unsupported_file_encoding: { code: 5013, category: ts.DiagnosticCategory.Error, key: "Unsupported_file_encoding_5013", message: "Unsupported file encoding." },
        Failed_to_parse_file_0_Colon_1: { code: 5014, category: ts.DiagnosticCategory.Error, key: "Failed_to_parse_file_0_Colon_1_5014", message: "Failed to parse file '{0}': {1}." },
        Unknown_compiler_option_0: { code: 5023, category: ts.DiagnosticCategory.Error, key: "Unknown_compiler_option_0_5023", message: "Unknown compiler option '{0}'." },
        Compiler_option_0_requires_a_value_of_type_1: { code: 5024, category: ts.DiagnosticCategory.Error, key: "Compiler_option_0_requires_a_value_of_type_1_5024", message: "Compiler option '{0}' requires a value of type {1}." },
        Could_not_write_file_0_Colon_1: { code: 5033, category: ts.DiagnosticCategory.Error, key: "Could_not_write_file_0_Colon_1_5033", message: "Could not write file '{0}': {1}" },
        Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: ts.DiagnosticCategory.Error, key: "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", message: "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: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", message: "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: { code: 5051, category: ts.DiagnosticCategory.Error, key: "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", message: "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." },
        Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: ts.DiagnosticCategory.Error, key: "Option_0_cannot_be_specified_without_specifying_option_1_5052", message: "Option '{0}' cannot be specified without specifying option '{1}'." },
        Option_0_cannot_be_specified_with_option_1: { code: 5053, category: ts.DiagnosticCategory.Error, key: "Option_0_cannot_be_specified_with_option_1_5053", message: "Option '{0}' cannot be specified with option '{1}'." },
        A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5054, category: ts.DiagnosticCategory.Error, key: "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", message: "A 'tsconfig.json' file is already defined at: '{0}'." },
        Cannot_write_file_0_because_it_would_overwrite_input_file: { code: 5055, category: ts.DiagnosticCategory.Error, key: "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", message: "Cannot write file '{0}' because it would overwrite input file." },
        Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: { code: 5056, category: ts.DiagnosticCategory.Error, key: "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", message: "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: { code: 5057, category: ts.DiagnosticCategory.Error, key: "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", message: "Cannot find a tsconfig.json file at the specified directory: '{0}'" },
        The_specified_path_does_not_exist_Colon_0: { code: 5058, category: ts.DiagnosticCategory.Error, key: "The_specified_path_does_not_exist_Colon_0_5058", message: "The specified path does not exist: '{0}'" },
        Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: { code: 5059, category: ts.DiagnosticCategory.Error, key: "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", message: "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier." },
        Option_paths_cannot_be_used_without_specifying_baseUrl_option: { code: 5060, category: ts.DiagnosticCategory.Error, key: "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", message: "Option 'paths' cannot be used without specifying '--baseUrl' option." },
        Pattern_0_can_have_at_most_one_Asterisk_character: { code: 5061, category: ts.DiagnosticCategory.Error, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", message: "Pattern '{0}' can have at most one '*' character" },
        Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: { code: 5062, category: ts.DiagnosticCategory.Error, key: "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", message: "Substitution '{0}' in pattern '{1}' in can have at most one '*' character" },
        Substitutions_for_pattern_0_should_be_an_array: { code: 5063, category: ts.DiagnosticCategory.Error, key: "Substitutions_for_pattern_0_should_be_an_array_5063", message: "Substitutions for pattern '{0}' should be an array." },
        Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: { code: 5064, category: ts.DiagnosticCategory.Error, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", message: "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: { code: 5065, category: ts.DiagnosticCategory.Error, key: "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", message: "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'." },
        Concatenate_and_emit_output_to_single_file: { code: 6001, category: ts.DiagnosticCategory.Message, key: "Concatenate_and_emit_output_to_single_file_6001", message: "Concatenate and emit output to single file." },
        Generates_corresponding_d_ts_file: { code: 6002, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_d_ts_file_6002", message: "Generates corresponding '.d.ts' file." },
        Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: ts.DiagnosticCategory.Message, key: "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", message: "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: { code: 6004, category: ts.DiagnosticCategory.Message, key: "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", message: "Specify the location where debugger should locate TypeScript files instead of source locations." },
        Watch_input_files: { code: 6005, category: ts.DiagnosticCategory.Message, key: "Watch_input_files_6005", message: "Watch input files." },
        Redirect_output_structure_to_the_directory: { code: 6006, category: ts.DiagnosticCategory.Message, key: "Redirect_output_structure_to_the_directory_6006", message: "Redirect output structure to the directory." },
        Do_not_erase_const_enum_declarations_in_generated_code: { code: 6007, category: ts.DiagnosticCategory.Message, key: "Do_not_erase_const_enum_declarations_in_generated_code_6007", message: "Do not erase const enum declarations in generated code." },
        Do_not_emit_outputs_if_any_errors_were_reported: { code: 6008, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_if_any_errors_were_reported_6008", message: "Do not emit outputs if any errors were reported." },
        Do_not_emit_comments_to_output: { code: 6009, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_comments_to_output_6009", message: "Do not emit comments to output." },
        Do_not_emit_outputs: { code: 6010, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_outputs_6010", message: "Do not emit outputs." },
        Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: { code: 6011, category: ts.DiagnosticCategory.Message, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", message: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking." },
        Skip_type_checking_of_declaration_files: { code: 6012, category: ts.DiagnosticCategory.Message, key: "Skip_type_checking_of_declaration_files_6012", message: "Skip type checking of declaration files." },
        Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015: { code: 6015, category: ts.DiagnosticCategory.Message, key: "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_6015", message: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'" },
        Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015: { code: 6016, category: ts.DiagnosticCategory.Message, key: "Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015_6016", message: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'" },
        Print_this_message: { code: 6017, category: ts.DiagnosticCategory.Message, key: "Print_this_message_6017", message: "Print this message." },
        Print_the_compiler_s_version: { code: 6019, category: ts.DiagnosticCategory.Message, key: "Print_the_compiler_s_version_6019", message: "Print the compiler's version." },
        Compile_the_project_in_the_given_directory: { code: 6020, category: ts.DiagnosticCategory.Message, key: "Compile_the_project_in_the_given_directory_6020", message: "Compile the project in the given directory." },
        Syntax_Colon_0: { code: 6023, category: ts.DiagnosticCategory.Message, key: "Syntax_Colon_0_6023", message: "Syntax: {0}" },
        options: { code: 6024, category: ts.DiagnosticCategory.Message, key: "options_6024", message: "options" },
        file: { code: 6025, category: ts.DiagnosticCategory.Message, key: "file_6025", message: "file" },
        Examples_Colon_0: { code: 6026, category: ts.DiagnosticCategory.Message, key: "Examples_Colon_0_6026", message: "Examples: {0}" },
        Options_Colon: { code: 6027, category: ts.DiagnosticCategory.Message, key: "Options_Colon_6027", message: "Options:" },
        Version_0: { code: 6029, category: ts.DiagnosticCategory.Message, key: "Version_0_6029", message: "Version {0}" },
        Insert_command_line_options_and_files_from_a_file: { code: 6030, category: ts.DiagnosticCategory.Message, key: "Insert_command_line_options_and_files_from_a_file_6030", message: "Insert command line options and files from a file." },
        File_change_detected_Starting_incremental_compilation: { code: 6032, category: ts.DiagnosticCategory.Message, key: "File_change_detected_Starting_incremental_compilation_6032", message: "File change detected. Starting incremental compilation..." },
        KIND: { code: 6034, category: ts.DiagnosticCategory.Message, key: "KIND_6034", message: "KIND" },
        FILE: { code: 6035, category: ts.DiagnosticCategory.Message, key: "FILE_6035", message: "FILE" },
        VERSION: { code: 6036, category: ts.DiagnosticCategory.Message, key: "VERSION_6036", message: "VERSION" },
        LOCATION: { code: 6037, category: ts.DiagnosticCategory.Message, key: "LOCATION_6037", message: "LOCATION" },
        DIRECTORY: { code: 6038, category: ts.DiagnosticCategory.Message, key: "DIRECTORY_6038", message: "DIRECTORY" },
        Compilation_complete_Watching_for_file_changes: { code: 6042, category: ts.DiagnosticCategory.Message, key: "Compilation_complete_Watching_for_file_changes_6042", message: "Compilation complete. Watching for file changes." },
        Generates_corresponding_map_file: { code: 6043, category: ts.DiagnosticCategory.Message, key: "Generates_corresponding_map_file_6043", message: "Generates corresponding '.map' file." },
        Compiler_option_0_expects_an_argument: { code: 6044, category: ts.DiagnosticCategory.Error, key: "Compiler_option_0_expects_an_argument_6044", message: "Compiler option '{0}' expects an argument." },
        Unterminated_quoted_string_in_response_file_0: { code: 6045, category: ts.DiagnosticCategory.Error, key: "Unterminated_quoted_string_in_response_file_0_6045", message: "Unterminated quoted string in response file '{0}'." },
        Argument_for_0_option_must_be_Colon_1: { code: 6046, category: ts.DiagnosticCategory.Error, key: "Argument_for_0_option_must_be_Colon_1_6046", message: "Argument for '{0}' option must be: {1}" },
        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: { code: 6048, category: ts.DiagnosticCategory.Error, key: "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", message: "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'." },
        Unsupported_locale_0: { code: 6049, category: ts.DiagnosticCategory.Error, key: "Unsupported_locale_0_6049", message: "Unsupported locale '{0}'." },
        Unable_to_open_file_0: { code: 6050, category: ts.DiagnosticCategory.Error, key: "Unable_to_open_file_0_6050", message: "Unable to open file '{0}'." },
        Corrupted_locale_file_0: { code: 6051, category: ts.DiagnosticCategory.Error, key: "Corrupted_locale_file_0_6051", message: "Corrupted locale file {0}." },
        Raise_error_on_expressions_and_declarations_with_an_implied_any_type: { code: 6052, category: ts.DiagnosticCategory.Message, key: "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", message: "Raise error on expressions and declarations with an implied 'any' type." },
        File_0_not_found: { code: 6053, category: ts.DiagnosticCategory.Error, key: "File_0_not_found_6053", message: "File '{0}' not found." },
        File_0_has_unsupported_extension_The_only_supported_extensions_are_1: { code: 6054, category: ts.DiagnosticCategory.Error, key: "File_0_has_unsupported_extension_The_only_supported_extensions_are_1_6054", message: "File '{0}' has unsupported extension. The only supported extensions are {1}." },
        Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: { code: 6055, category: ts.DiagnosticCategory.Message, key: "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", message: "Suppress noImplicitAny errors for indexing objects lacking index signatures." },
        Do_not_emit_declarations_for_code_that_has_an_internal_annotation: { code: 6056, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", message: "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: { code: 6058, category: ts.DiagnosticCategory.Message, key: "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", message: "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: { code: 6059, category: ts.DiagnosticCategory.Error, key: "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", message: "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: { code: 6060, category: ts.DiagnosticCategory.Message, key: "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", message: "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." },
        NEWLINE: { code: 6061, category: ts.DiagnosticCategory.Message, key: "NEWLINE_6061", message: "NEWLINE" },
        Option_0_can_only_be_specified_in_tsconfig_json_file: { code: 6064, category: ts.DiagnosticCategory.Error, key: "Option_0_can_only_be_specified_in_tsconfig_json_file_6064", message: "Option '{0}' can only be specified in 'tsconfig.json' file." },
        Enables_experimental_support_for_ES7_decorators: { code: 6065, category: ts.DiagnosticCategory.Message, key: "Enables_experimental_support_for_ES7_decorators_6065", message: "Enables experimental support for ES7 decorators." },
        Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", message: "Enables experimental support for emitting type metadata for decorators." },
        Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables_experimental_support_for_ES7_async_functions_6068", message: "Enables experimental support for ES7 async functions." },
        Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", message: "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)." },
        Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: { code: 6070, category: ts.DiagnosticCategory.Message, key: "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", message: "Initializes a TypeScript project and creates a tsconfig.json file." },
        Successfully_created_a_tsconfig_json_file: { code: 6071, category: ts.DiagnosticCategory.Message, key: "Successfully_created_a_tsconfig_json_file_6071", message: "Successfully created a tsconfig.json file." },
        Suppress_excess_property_checks_for_object_literals: { code: 6072, category: ts.DiagnosticCategory.Message, key: "Suppress_excess_property_checks_for_object_literals_6072", message: "Suppress excess property checks for object literals." },
        Stylize_errors_and_messages_using_color_and_context_experimental: { code: 6073, category: ts.DiagnosticCategory.Message, key: "Stylize_errors_and_messages_using_color_and_context_experimental_6073", message: "Stylize errors and messages using color and context. (experimental)" },
        Do_not_report_errors_on_unused_labels: { code: 6074, category: ts.DiagnosticCategory.Message, key: "Do_not_report_errors_on_unused_labels_6074", message: "Do not report errors on unused labels." },
        Report_error_when_not_all_code_paths_in_function_return_a_value: { code: 6075, category: ts.DiagnosticCategory.Message, key: "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", message: "Report error when not all code paths in function return a value." },
        Report_errors_for_fallthrough_cases_in_switch_statement: { code: 6076, category: ts.DiagnosticCategory.Message, key: "Report_errors_for_fallthrough_cases_in_switch_statement_6076", message: "Report errors for fallthrough cases in switch statement." },
        Do_not_report_errors_on_unreachable_code: { code: 6077, category: ts.DiagnosticCategory.Message, key: "Do_not_report_errors_on_unreachable_code_6077", message: "Do not report errors on unreachable code." },
        Disallow_inconsistently_cased_references_to_the_same_file: { code: 6078, category: ts.DiagnosticCategory.Message, key: "Disallow_inconsistently_cased_references_to_the_same_file_6078", message: "Disallow inconsistently-cased references to the same file." },
        Specify_library_files_to_be_included_in_the_compilation_Colon: { code: 6079, category: ts.DiagnosticCategory.Message, key: "Specify_library_files_to_be_included_in_the_compilation_Colon_6079", message: "Specify library files to be included in the compilation: " },
        Specify_JSX_code_generation_Colon_preserve_or_react: { code: 6080, category: ts.DiagnosticCategory.Message, key: "Specify_JSX_code_generation_Colon_preserve_or_react_6080", message: "Specify JSX code generation: 'preserve' or 'react'" },
        Only_amd_and_system_modules_are_supported_alongside_0: { code: 6082, category: ts.DiagnosticCategory.Error, key: "Only_amd_and_system_modules_are_supported_alongside_0_6082", message: "Only 'amd' and 'system' modules are supported alongside --{0}." },
        Base_directory_to_resolve_non_absolute_module_names: { code: 6083, category: ts.DiagnosticCategory.Message, key: "Base_directory_to_resolve_non_absolute_module_names_6083", message: "Base directory to resolve non-absolute module names." },
        Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit: { code: 6084, category: ts.DiagnosticCategory.Message, key: "Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit_6084", message: "Specify the object invoked for createElement and __spread when targeting 'react' JSX emit" },
        Enable_tracing_of_the_name_resolution_process: { code: 6085, category: ts.DiagnosticCategory.Message, key: "Enable_tracing_of_the_name_resolution_process_6085", message: "Enable tracing of the name resolution process." },
        Resolving_module_0_from_1: { code: 6086, category: ts.DiagnosticCategory.Message, key: "Resolving_module_0_from_1_6086", message: "======== Resolving module '{0}' from '{1}'. ========" },
        Explicitly_specified_module_resolution_kind_Colon_0: { code: 6087, category: ts.DiagnosticCategory.Message, key: "Explicitly_specified_module_resolution_kind_Colon_0_6087", message: "Explicitly specified module resolution kind: '{0}'." },
        Module_resolution_kind_is_not_specified_using_0: { code: 6088, category: ts.DiagnosticCategory.Message, key: "Module_resolution_kind_is_not_specified_using_0_6088", message: "Module resolution kind is not specified, using '{0}'." },
        Module_name_0_was_successfully_resolved_to_1: { code: 6089, category: ts.DiagnosticCategory.Message, key: "Module_name_0_was_successfully_resolved_to_1_6089", message: "======== Module name '{0}' was successfully resolved to '{1}'. ========" },
        Module_name_0_was_not_resolved: { code: 6090, category: ts.DiagnosticCategory.Message, key: "Module_name_0_was_not_resolved_6090", message: "======== Module name '{0}' was not resolved. ========" },
        paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: { code: 6091, category: ts.DiagnosticCategory.Message, key: "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", message: "'paths' option is specified, looking for a pattern to match module name '{0}'." },
        Module_name_0_matched_pattern_1: { code: 6092, category: ts.DiagnosticCategory.Message, key: "Module_name_0_matched_pattern_1_6092", message: "Module name '{0}', matched pattern '{1}'." },
        Trying_substitution_0_candidate_module_location_Colon_1: { code: 6093, category: ts.DiagnosticCategory.Message, key: "Trying_substitution_0_candidate_module_location_Colon_1_6093", message: "Trying substitution '{0}', candidate module location: '{1}'." },
        Resolving_module_name_0_relative_to_base_url_1_2: { code: 6094, category: ts.DiagnosticCategory.Message, key: "Resolving_module_name_0_relative_to_base_url_1_2_6094", message: "Resolving module name '{0}' relative to base url '{1}' - '{2}'." },
        Loading_module_as_file_Slash_folder_candidate_module_location_0: { code: 6095, category: ts.DiagnosticCategory.Message, key: "Loading_module_as_file_Slash_folder_candidate_module_location_0_6095", message: "Loading module as file / folder, candidate module location '{0}'." },
        File_0_does_not_exist: { code: 6096, category: ts.DiagnosticCategory.Message, key: "File_0_does_not_exist_6096", message: "File '{0}' does not exist." },
        File_0_exist_use_it_as_a_name_resolution_result: { code: 6097, category: ts.DiagnosticCategory.Message, key: "File_0_exist_use_it_as_a_name_resolution_result_6097", message: "File '{0}' exist - use it as a name resolution result." },
        Loading_module_0_from_node_modules_folder: { code: 6098, category: ts.DiagnosticCategory.Message, key: "Loading_module_0_from_node_modules_folder_6098", message: "Loading module '{0}' from 'node_modules' folder." },
        Found_package_json_at_0: { code: 6099, category: ts.DiagnosticCategory.Message, key: "Found_package_json_at_0_6099", message: "Found 'package.json' at '{0}'." },
        package_json_does_not_have_types_field: { code: 6100, category: ts.DiagnosticCategory.Message, key: "package_json_does_not_have_types_field_6100", message: "'package.json' does not have 'types' field." },
        package_json_has_0_field_1_that_references_2: { code: 6101, category: ts.DiagnosticCategory.Message, key: "package_json_has_0_field_1_that_references_2_6101", message: "'package.json' has '{0}' field '{1}' that references '{2}'." },
        Allow_javascript_files_to_be_compiled: { code: 6102, category: ts.DiagnosticCategory.Message, key: "Allow_javascript_files_to_be_compiled_6102", message: "Allow javascript files to be compiled." },
        Option_0_should_have_array_of_strings_as_a_value: { code: 6103, category: ts.DiagnosticCategory.Error, key: "Option_0_should_have_array_of_strings_as_a_value_6103", message: "Option '{0}' should have array of strings as a value." },
        Checking_if_0_is_the_longest_matching_prefix_for_1_2: { code: 6104, category: ts.DiagnosticCategory.Message, key: "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", message: "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'." },
        Expected_type_of_0_field_in_package_json_to_be_string_got_1: { code: 6105, category: ts.DiagnosticCategory.Message, key: "Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105", message: "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: { code: 6106, category: ts.DiagnosticCategory.Message, key: "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", message: "'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: { code: 6107, category: ts.DiagnosticCategory.Message, key: "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", message: "'rootDirs' option is set, using it to resolve relative module name '{0}'" },
        Longest_matching_prefix_for_0_is_1: { code: 6108, category: ts.DiagnosticCategory.Message, key: "Longest_matching_prefix_for_0_is_1_6108", message: "Longest matching prefix for '{0}' is '{1}'" },
        Loading_0_from_the_root_dir_1_candidate_location_2: { code: 6109, category: ts.DiagnosticCategory.Message, key: "Loading_0_from_the_root_dir_1_candidate_location_2_6109", message: "Loading '{0}' from the root dir '{1}', candidate location '{2}'" },
        Trying_other_entries_in_rootDirs: { code: 6110, category: ts.DiagnosticCategory.Message, key: "Trying_other_entries_in_rootDirs_6110", message: "Trying other entries in 'rootDirs'" },
        Module_resolution_using_rootDirs_has_failed: { code: 6111, category: ts.DiagnosticCategory.Message, key: "Module_resolution_using_rootDirs_has_failed_6111", message: "Module resolution using 'rootDirs' has failed" },
        Do_not_emit_use_strict_directives_in_module_output: { code: 6112, category: ts.DiagnosticCategory.Message, key: "Do_not_emit_use_strict_directives_in_module_output_6112", message: "Do not emit 'use strict' directives in module output." },
        Enable_strict_null_checks: { code: 6113, category: ts.DiagnosticCategory.Message, key: "Enable_strict_null_checks_6113", message: "Enable strict null checks." },
        Unknown_option_excludes_Did_you_mean_exclude: { code: 6114, category: ts.DiagnosticCategory.Error, key: "Unknown_option_excludes_Did_you_mean_exclude_6114", message: "Unknown option 'excludes'. Did you mean 'exclude'?" },
        Raise_error_on_this_expressions_with_an_implied_any_type: { code: 6115, category: ts.DiagnosticCategory.Message, key: "Raise_error_on_this_expressions_with_an_implied_any_type_6115", message: "Raise error on 'this' expressions with an implied 'any' type." },
        Resolving_type_reference_directive_0_containing_file_1_root_directory_2: { code: 6116, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", message: "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========" },
        Resolving_using_primary_search_paths: { code: 6117, category: ts.DiagnosticCategory.Message, key: "Resolving_using_primary_search_paths_6117", message: "Resolving using primary search paths..." },
        Resolving_from_node_modules_folder: { code: 6118, category: ts.DiagnosticCategory.Message, key: "Resolving_from_node_modules_folder_6118", message: "Resolving from node_modules folder..." },
        Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: { code: 6119, category: ts.DiagnosticCategory.Message, key: "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", message: "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========" },
        Type_reference_directive_0_was_not_resolved: { code: 6120, category: ts.DiagnosticCategory.Message, key: "Type_reference_directive_0_was_not_resolved_6120", message: "======== Type reference directive '{0}' was not resolved. ========" },
        Resolving_with_primary_search_path_0: { code: 6121, category: ts.DiagnosticCategory.Message, key: "Resolving_with_primary_search_path_0_6121", message: "Resolving with primary search path '{0}'" },
        Root_directory_cannot_be_determined_skipping_primary_search_paths: { code: 6122, category: ts.DiagnosticCategory.Message, key: "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", message: "Root directory cannot be determined, skipping primary search paths." },
        Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: { code: 6123, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", message: "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========" },
        Type_declaration_files_to_be_included_in_compilation: { code: 6124, category: ts.DiagnosticCategory.Message, key: "Type_declaration_files_to_be_included_in_compilation_6124", message: "Type declaration files to be included in compilation." },
        Looking_up_in_node_modules_folder_initial_location_0: { code: 6125, category: ts.DiagnosticCategory.Message, key: "Looking_up_in_node_modules_folder_initial_location_0_6125", message: "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: { code: 6126, category: ts.DiagnosticCategory.Message, key: "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", message: "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: { code: 6127, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", message: "======== 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: { code: 6128, category: ts.DiagnosticCategory.Message, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", message: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========" },
        The_config_file_0_found_doesn_t_contain_any_source_files: { code: 6129, category: ts.DiagnosticCategory.Error, key: "The_config_file_0_found_doesn_t_contain_any_source_files_6129", message: "The config file '{0}' found doesn't contain any source files." },
        Resolving_real_path_for_0_result_1: { code: 6130, category: ts.DiagnosticCategory.Message, key: "Resolving_real_path_for_0_result_1_6130", message: "Resolving real path for '{0}', result '{1}'" },
        Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: { code: 6131, category: ts.DiagnosticCategory.Error, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", message: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'." },
        File_name_0_has_a_1_extension_stripping_it: { code: 6132, category: ts.DiagnosticCategory.Message, key: "File_name_0_has_a_1_extension_stripping_it_6132", message: "File name '{0}' has a '{1}' extension - stripping it" },
        _0_is_declared_but_never_used: { code: 6133, category: ts.DiagnosticCategory.Error, key: "_0_is_declared_but_never_used_6133", message: "'{0}' is declared but never used." },
        Report_Errors_on_Unused_Locals: { code: 6134, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Locals_6134", message: "Report Errors on Unused Locals." },
        Report_Errors_on_Unused_Parameters: { code: 6135, category: ts.DiagnosticCategory.Message, key: "Report_Errors_on_Unused_Parameters_6135", message: "Report Errors on Unused Parameters." },
        The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: { code: 6136, category: ts.DiagnosticCategory.Message, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", message: "The maximum dependency depth to search under node_modules and load JavaScript files" },
        No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0: { code: 6137, category: ts.DiagnosticCategory.Message, key: "No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0_6137", message: "No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'" },
        Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable_0_implicitly_has_an_1_type_7005", message: "Variable '{0}' implicitly has an '{1}' type." },
        Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter_0_implicitly_has_an_1_type_7006", message: "Parameter '{0}' implicitly has an '{1}' type." },
        Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member_0_implicitly_has_an_1_type_7008", message: "Member '{0}' implicitly has an '{1}' type." },
        new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: { code: 7009, category: ts.DiagnosticCategory.Error, key: "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", message: "'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: { code: 7010, category: ts.DiagnosticCategory.Error, key: "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", message: "'{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: { code: 7011, category: ts.DiagnosticCategory.Error, key: "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", message: "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: { code: 7013, category: ts.DiagnosticCategory.Error, key: "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", message: "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: { code: 7015, category: ts.DiagnosticCategory.Error, key: "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", message: "Element implicitly has an 'any' type because index expression is not of type 'number'." },
        Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation: { code: 7016, category: ts.DiagnosticCategory.Error, key: "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation_7016", message: "Property '{0}' implicitly has type 'any', because its 'set' accessor lacks a type annotation." },
        Index_signature_of_object_type_implicitly_has_an_any_type: { code: 7017, category: ts.DiagnosticCategory.Error, key: "Index_signature_of_object_type_implicitly_has_an_any_type_7017", message: "Index signature of object type implicitly has an 'any' type." },
        Object_literal_s_property_0_implicitly_has_an_1_type: { code: 7018, category: ts.DiagnosticCategory.Error, key: "Object_literal_s_property_0_implicitly_has_an_1_type_7018", message: "Object literal's property '{0}' implicitly has an '{1}' type." },
        Rest_parameter_0_implicitly_has_an_any_type: { code: 7019, category: ts.DiagnosticCategory.Error, key: "Rest_parameter_0_implicitly_has_an_any_type_7019", message: "Rest parameter '{0}' implicitly has an 'any[]' type." },
        Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7020, category: ts.DiagnosticCategory.Error, key: "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", message: "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: { code: 7022, category: ts.DiagnosticCategory.Error, key: "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", message: "'{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: { code: 7023, category: ts.DiagnosticCategory.Error, key: "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", message: "'{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: { code: 7024, category: ts.DiagnosticCategory.Error, key: "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", message: "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: { code: 7025, category: ts.DiagnosticCategory.Error, key: "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025", message: "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: { code: 7026, category: ts.DiagnosticCategory.Error, key: "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", message: "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists" },
        Unreachable_code_detected: { code: 7027, category: ts.DiagnosticCategory.Error, key: "Unreachable_code_detected_7027", message: "Unreachable code detected." },
        Unused_label: { code: 7028, category: ts.DiagnosticCategory.Error, key: "Unused_label_7028", message: "Unused label." },
        Fallthrough_case_in_switch: { code: 7029, category: ts.DiagnosticCategory.Error, key: "Fallthrough_case_in_switch_7029", message: "Fallthrough case in switch." },
        Not_all_code_paths_return_a_value: { code: 7030, category: ts.DiagnosticCategory.Error, key: "Not_all_code_paths_return_a_value_7030", message: "Not all code paths return a value." },
        Binding_element_0_implicitly_has_an_1_type: { code: 7031, category: ts.DiagnosticCategory.Error, key: "Binding_element_0_implicitly_has_an_1_type_7031", message: "Binding element '{0}' implicitly has an '{1}' type." },
        You_cannot_rename_this_element: { code: 8000, category: ts.DiagnosticCategory.Error, key: "You_cannot_rename_this_element_8000", message: "You cannot rename this element." },
        You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: ts.DiagnosticCategory.Error, key: "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", message: "You cannot rename elements that are defined in the standard TypeScript library." },
        import_can_only_be_used_in_a_ts_file: { code: 8002, category: ts.DiagnosticCategory.Error, key: "import_can_only_be_used_in_a_ts_file_8002", message: "'import ... =' can only be used in a .ts file." },
        export_can_only_be_used_in_a_ts_file: { code: 8003, category: ts.DiagnosticCategory.Error, key: "export_can_only_be_used_in_a_ts_file_8003", message: "'export=' can only be used in a .ts file." },
        type_parameter_declarations_can_only_be_used_in_a_ts_file: { code: 8004, category: ts.DiagnosticCategory.Error, key: "type_parameter_declarations_can_only_be_used_in_a_ts_file_8004", message: "'type parameter declarations' can only be used in a .ts file." },
        implements_clauses_can_only_be_used_in_a_ts_file: { code: 8005, category: ts.DiagnosticCategory.Error, key: "implements_clauses_can_only_be_used_in_a_ts_file_8005", message: "'implements clauses' can only be used in a .ts file." },
        interface_declarations_can_only_be_used_in_a_ts_file: { code: 8006, category: ts.DiagnosticCategory.Error, key: "interface_declarations_can_only_be_used_in_a_ts_file_8006", message: "'interface declarations' can only be used in a .ts file." },
        module_declarations_can_only_be_used_in_a_ts_file: { code: 8007, category: ts.DiagnosticCategory.Error, key: "module_declarations_can_only_be_used_in_a_ts_file_8007", message: "'module declarations' can only be used in a .ts file." },
        type_aliases_can_only_be_used_in_a_ts_file: { code: 8008, category: ts.DiagnosticCategory.Error, key: "type_aliases_can_only_be_used_in_a_ts_file_8008", message: "'type aliases' can only be used in a .ts file." },
        _0_can_only_be_used_in_a_ts_file: { code: 8009, category: ts.DiagnosticCategory.Error, key: "_0_can_only_be_used_in_a_ts_file_8009", message: "'{0}' can only be used in a .ts file." },
        types_can_only_be_used_in_a_ts_file: { code: 8010, category: ts.DiagnosticCategory.Error, key: "types_can_only_be_used_in_a_ts_file_8010", message: "'types' can only be used in a .ts file." },
        type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: ts.DiagnosticCategory.Error, key: "type_arguments_can_only_be_used_in_a_ts_file_8011", message: "'type arguments' can only be used in a .ts file." },
        parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: ts.DiagnosticCategory.Error, key: "parameter_modifiers_can_only_be_used_in_a_ts_file_8012", message: "'parameter modifiers' can only be used in a .ts file." },
        enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: ts.DiagnosticCategory.Error, key: "enum_declarations_can_only_be_used_in_a_ts_file_8015", message: "'enum declarations' can only be used in a .ts file." },
        type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: ts.DiagnosticCategory.Error, key: "type_assertion_expressions_can_only_be_used_in_a_ts_file_8016", message: "'type assertion expressions' can only be used in a .ts file." },
        Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: ts.DiagnosticCategory.Error, key: "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", message: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." },
        class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "class_expressions_are_not_currently_supported_9003", message: "'class' expressions are not currently supported." },
        JSX_attributes_must_only_be_assigned_a_non_empty_expression: { code: 17000, category: ts.DiagnosticCategory.Error, key: "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", message: "JSX attributes must only be assigned a non-empty 'expression'." },
        JSX_elements_cannot_have_multiple_attributes_with_the_same_name: { code: 17001, category: ts.DiagnosticCategory.Error, key: "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", message: "JSX elements cannot have multiple attributes with the same name." },
        Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: ts.DiagnosticCategory.Error, key: "Expected_corresponding_JSX_closing_tag_for_0_17002", message: "Expected corresponding JSX closing tag for '{0}'." },
        JSX_attribute_expected: { code: 17003, category: ts.DiagnosticCategory.Error, key: "JSX_attribute_expected_17003", message: "JSX attribute expected." },
        Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: ts.DiagnosticCategory.Error, key: "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", message: "Cannot use JSX unless the '--jsx' flag is provided." },
        A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: { code: 17005, category: ts.DiagnosticCategory.Error, key: "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", message: "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: { code: 17006, category: ts.DiagnosticCategory.Error, key: "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", message: "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: { code: 17007, category: ts.DiagnosticCategory.Error, key: "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", message: "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: { code: 17008, category: ts.DiagnosticCategory.Error, key: "JSX_element_0_has_no_corresponding_closing_tag_17008", message: "JSX element '{0}' has no corresponding closing tag." },
        super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: { code: 17009, category: ts.DiagnosticCategory.Error, key: "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", message: "'super' must be called before accessing 'this' in the constructor of a derived class." },
        Unknown_typing_option_0: { code: 17010, category: ts.DiagnosticCategory.Error, key: "Unknown_typing_option_0_17010", message: "Unknown typing option '{0}'." }
    };
})(ts || (ts = {}));
/// <reference path="core.ts"/>
/// <reference path="diagnosticInformationMap.generated.ts"/>
var ts;
(function (ts) {
    /* @internal */
    function tokenIsIdentifierOrKeyword(token) {
        return token >= 69 /* Identifier */;
    }
    ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword;
    var textToToken = {
        "abstract": 115 /* AbstractKeyword */,
        "any": 117 /* AnyKeyword */,
        "as": 116 /* AsKeyword */,
        "boolean": 120 /* BooleanKeyword */,
        "break": 70 /* BreakKeyword */,
        "case": 71 /* CaseKeyword */,
        "catch": 72 /* CatchKeyword */,
        "class": 73 /* ClassKeyword */,
        "continue": 75 /* ContinueKeyword */,
        "const": 74 /* ConstKeyword */,
        "constructor": 121 /* ConstructorKeyword */,
        "debugger": 76 /* DebuggerKeyword */,
        "declare": 122 /* DeclareKeyword */,
        "default": 77 /* DefaultKeyword */,
        "delete": 78 /* DeleteKeyword */,
        "do": 79 /* DoKeyword */,
        "else": 80 /* ElseKeyword */,
        "enum": 81 /* EnumKeyword */,
        "export": 82 /* ExportKeyword */,
        "extends": 83 /* ExtendsKeyword */,
        "false": 84 /* FalseKeyword */,
        "finally": 85 /* FinallyKeyword */,
        "for": 86 /* ForKeyword */,
        "from": 136 /* FromKeyword */,
        "function": 87 /* FunctionKeyword */,
        "get": 123 /* GetKeyword */,
        "if": 88 /* IfKeyword */,
        "implements": 106 /* ImplementsKeyword */,
        "import": 89 /* ImportKeyword */,
        "in": 90 /* InKeyword */,
        "instanceof": 91 /* InstanceOfKeyword */,
        "interface": 107 /* InterfaceKeyword */,
        "is": 124 /* IsKeyword */,
        "let": 108 /* LetKeyword */,
        "module": 125 /* ModuleKeyword */,
        "namespace": 126 /* NamespaceKeyword */,
        "never": 127 /* NeverKeyword */,
        "new": 92 /* NewKeyword */,
        "null": 93 /* NullKeyword */,
        "number": 130 /* NumberKeyword */,
        "package": 109 /* PackageKeyword */,
        "private": 110 /* PrivateKeyword */,
        "protected": 111 /* ProtectedKeyword */,
        "public": 112 /* PublicKeyword */,
        "readonly": 128 /* ReadonlyKeyword */,
        "require": 129 /* RequireKeyword */,
        "global": 137 /* GlobalKeyword */,
        "return": 94 /* ReturnKeyword */,
        "set": 131 /* SetKeyword */,
        "static": 113 /* StaticKeyword */,
        "string": 132 /* StringKeyword */,
        "super": 95 /* SuperKeyword */,
        "switch": 96 /* SwitchKeyword */,
        "symbol": 133 /* SymbolKeyword */,
        "this": 97 /* ThisKeyword */,
        "throw": 98 /* ThrowKeyword */,
        "true": 99 /* TrueKeyword */,
        "try": 100 /* TryKeyword */,
        "type": 134 /* TypeKeyword */,
        "typeof": 101 /* TypeOfKeyword */,
        "undefined": 135 /* UndefinedKeyword */,
        "var": 102 /* VarKeyword */,
        "void": 103 /* VoidKeyword */,
        "while": 104 /* WhileKeyword */,
        "with": 105 /* WithKeyword */,
        "yield": 114 /* YieldKeyword */,
        "async": 118 /* AsyncKeyword */,
        "await": 119 /* AwaitKeyword */,
        "of": 138 /* OfKeyword */,
        "{": 15 /* OpenBraceToken */,
        "}": 16 /* CloseBraceToken */,
        "(": 17 /* OpenParenToken */,
        ")": 18 /* CloseParenToken */,
        "[": 19 /* OpenBracketToken */,
        "]": 20 /* CloseBracketToken */,
        ".": 21 /* DotToken */,
        "...": 22 /* DotDotDotToken */,
        ";": 23 /* SemicolonToken */,
        ",": 24 /* CommaToken */,
        "<": 25 /* LessThanToken */,
        ">": 27 /* GreaterThanToken */,
        "<=": 28 /* LessThanEqualsToken */,
        ">=": 29 /* GreaterThanEqualsToken */,
        "==": 30 /* EqualsEqualsToken */,
        "!=": 31 /* ExclamationEqualsToken */,
        "===": 32 /* EqualsEqualsEqualsToken */,
        "!==": 33 /* ExclamationEqualsEqualsToken */,
        "=>": 34 /* EqualsGreaterThanToken */,
        "+": 35 /* PlusToken */,
        "-": 36 /* MinusToken */,
        "**": 38 /* AsteriskAsteriskToken */,
        "*": 37 /* AsteriskToken */,
        "/": 39 /* SlashToken */,
        "%": 40 /* PercentToken */,
        "++": 41 /* PlusPlusToken */,
        "--": 42 /* MinusMinusToken */,
        "<<": 43 /* LessThanLessThanToken */,
        "</": 26 /* LessThanSlashToken */,
        ">>": 44 /* GreaterThanGreaterThanToken */,
        ">>>": 45 /* GreaterThanGreaterThanGreaterThanToken */,
        "&": 46 /* AmpersandToken */,
        "|": 47 /* BarToken */,
        "^": 48 /* CaretToken */,
        "!": 49 /* ExclamationToken */,
        "~": 50 /* TildeToken */,
        "&&": 51 /* AmpersandAmpersandToken */,
        "||": 52 /* BarBarToken */,
        "?": 53 /* QuestionToken */,
        ":": 54 /* ColonToken */,
        "=": 56 /* EqualsToken */,
        "+=": 57 /* PlusEqualsToken */,
        "-=": 58 /* MinusEqualsToken */,
        "*=": 59 /* AsteriskEqualsToken */,
        "**=": 60 /* AsteriskAsteriskEqualsToken */,
        "/=": 61 /* SlashEqualsToken */,
        "%=": 62 /* PercentEqualsToken */,
        "<<=": 63 /* LessThanLessThanEqualsToken */,
        ">>=": 64 /* GreaterThanGreaterThanEqualsToken */,
        ">>>=": 65 /* GreaterThanGreaterThanGreaterThanEqualsToken */,
        "&=": 66 /* AmpersandEqualsToken */,
        "|=": 67 /* BarEqualsToken */,
        "^=": 68 /* CaretEqualsToken */,
        "@": 55 /* 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 = [];
        for (var name_4 in source) {
            if (source.hasOwnProperty(name_4)) {
                result[source[name_4]] = name_4;
            }
        }
        return result;
    }
    var tokenStrings = makeReverseMap(textToToken);
    function tokenToString(t) {
        return tokenStrings[t];
    }
    ts.tokenToString = tokenToString;
    /* @internal */
    function stringToToken(s) {
        return textToToken[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++;
                    }
                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);
    }
    ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
    /* @internal */
    function computePositionOfLineAndCharacter(lineStarts, line, character) {
        ts.Debug.assert(line >= 0 && line < lineStarts.length);
        return lineStarts[line] + character;
    }
    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;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    function isWhiteSpace(ch) {
        return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
    }
    ts.isWhiteSpace = isWhiteSpace;
    /** 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 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; }
        // Using ! with a greater than test is a fast way of testing the following conditions:
        //  pos === undefined || pos === null || isNaN(pos) || pos < 0;
        if (!(pos >= 0)) {
            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++;
                    }
                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 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 */ && (isWhiteSpace(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, n = mergeConflictMarkerLength; i < n; 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 === 61 /* equals */);
            // Consume everything from the start of the mid-conflict marker to the start of the next
            // end-conflict marker.
            while (pos < len) {
                var ch_1 = text.charCodeAt(pos);
                if (ch_1 === 62 /* greaterThan */ && 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;
    }
    /**
     * Extract comments from text prefixing the token closest following `pos`.
     * The return value is an array containing a TextRange for each comment.
     * Single-line comment ranges include the beginning '//' characters but not the ending line break.
     * Multi - line comment ranges include the beginning '/* and ending '<asterisk>/' characters.
     * The return value is undefined if no comments were found.
     * @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.
     */
    function getCommentRanges(text, pos, trailing) {
        var result;
        var collecting = trailing || pos === 0;
        while (pos < text.length) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                case 10 /* lineFeed */:
                    pos++;
                    if (trailing) {
                        return result;
                    }
                    collecting = true;
                    if (result && result.length) {
                        ts.lastOrUndefined(result).hasTrailingNewLine = 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 (!result) {
                                result = [];
                            }
                            result.push({ pos: startPos, end: pos, hasTrailingNewLine: hasTrailingNewLine, kind: kind });
                        }
                        continue;
                    }
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpace(ch))) {
                        if (result && result.length && isLineBreak(ch)) {
                            ts.lastOrUndefined(result).hasTrailingNewLine = true;
                        }
                        pos++;
                        continue;
                    }
                    break;
            }
            return result;
        }
        return result;
    }
    function getLeadingCommentRanges(text, pos) {
        return getCommentRanges(text, pos, /*trailing*/ false);
    }
    ts.getLeadingCommentRanges = getLeadingCommentRanges;
    function getTrailingCommentRanges(text, pos) {
        return getCommentRanges(text, pos, /*trailing*/ true);
    }
    ts.getTrailingCommentRanges = getTrailingCommentRanges;
    /** Optionally, get the shebang */
    function getShebang(text) {
        return shebangTriviaRegex.test(text)
            ? shebangTriviaRegex.exec(text)[0]
            : undefined;
    }
    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 isIdentifier(name, languageVersion) {
        if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) {
            return false;
        }
        for (var i = 1, n = name.length; i < n; i++) {
            if (!isIdentifierPart(name.charCodeAt(i), languageVersion)) {
                return false;
            }
        }
        return true;
    }
    ts.isIdentifier = isIdentifier;
    // 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;
        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 === 69 /* Identifier */ || token > 105 /* LastReservedWord */; },
            isReservedWord: function () { return token >= 70 /* FirstReservedWord */ && token <= 105 /* LastReservedWord */; },
            isUnterminated: function () { return tokenIsUnterminated; },
            reScanGreaterToken: reScanGreaterToken,
            reScanSlashToken: reScanSlashToken,
            reScanTemplateToken: reScanTemplateToken,
            scanJsxIdentifier: scanJsxIdentifier,
            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++;
                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() {
            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 */) {
                    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 ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */;
                    break;
                }
                var currChar = text.charCodeAt(pos);
                // '`'
                if (currChar === 96 /* backtick */) {
                    contents += text.substring(start, pos);
                    pos++;
                    resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */;
                    break;
                }
                // '${'
                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                    contents += text.substring(start, pos);
                    pos += 2;
                    resultingToken = startedWithBacktick ? 12 /* TemplateHead */ : 13 /* 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++;
                    }
                // fall 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 */ && hasOwnProperty.call(textToToken, tokenValue)) {
                    return token = textToToken[tokenValue];
                }
            }
            return token = 69 /* 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;
            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 = 33 /* ExclamationEqualsEqualsToken */;
                            }
                            return pos += 2, token = 31 /* ExclamationEqualsToken */;
                        }
                        pos++;
                        return token = 49 /* 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 = 62 /* PercentEqualsToken */;
                        }
                        pos++;
                        return token = 40 /* PercentToken */;
                    case 38 /* ampersand */:
                        if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
                            return pos += 2, token = 51 /* AmpersandAmpersandToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 66 /* AmpersandEqualsToken */;
                        }
                        pos++;
                        return token = 46 /* AmpersandToken */;
                    case 40 /* openParen */:
                        pos++;
                        return token = 17 /* OpenParenToken */;
                    case 41 /* closeParen */:
                        pos++;
                        return token = 18 /* CloseParenToken */;
                    case 42 /* asterisk */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 59 /* AsteriskEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 60 /* AsteriskAsteriskEqualsToken */;
                            }
                            return pos += 2, token = 38 /* AsteriskAsteriskToken */;
                        }
                        pos++;
                        return token = 37 /* AsteriskToken */;
                    case 43 /* plus */:
                        if (text.charCodeAt(pos + 1) === 43 /* plus */) {
                            return pos += 2, token = 41 /* PlusPlusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 57 /* PlusEqualsToken */;
                        }
                        pos++;
                        return token = 35 /* PlusToken */;
                    case 44 /* comma */:
                        pos++;
                        return token = 24 /* CommaToken */;
                    case 45 /* minus */:
                        if (text.charCodeAt(pos + 1) === 45 /* minus */) {
                            return pos += 2, token = 42 /* MinusMinusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 58 /* MinusEqualsToken */;
                        }
                        pos++;
                        return token = 36 /* 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 = 22 /* DotDotDotToken */;
                        }
                        pos++;
                        return token = 21 /* 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_2 = text.charCodeAt(pos);
                                if (ch_2 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    commentClosed = true;
                                    break;
                                }
                                if (isLineBreak(ch_2)) {
                                    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 = 61 /* SlashEqualsToken */;
                        }
                        pos++;
                        return token = 39 /* 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;
                            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;
                            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;
                            return token = 8 /* NumericLiteral */;
                        }
                        // Try to parse as an octal
                        if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = "" + scanOctalDigits();
                            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).
                    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 = 54 /* ColonToken */;
                    case 59 /* semicolon */:
                        pos++;
                        return token = 23 /* 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 = 63 /* LessThanLessThanEqualsToken */;
                            }
                            return pos += 2, token = 43 /* LessThanLessThanToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 28 /* LessThanEqualsToken */;
                        }
                        if (languageVariant === 1 /* JSX */ &&
                            text.charCodeAt(pos + 1) === 47 /* slash */ &&
                            text.charCodeAt(pos + 2) !== 42 /* asterisk */) {
                            return pos += 2, token = 26 /* LessThanSlashToken */;
                        }
                        pos++;
                        return token = 25 /* 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 = 32 /* EqualsEqualsEqualsToken */;
                            }
                            return pos += 2, token = 30 /* EqualsEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                            return pos += 2, token = 34 /* EqualsGreaterThanToken */;
                        }
                        pos++;
                        return token = 56 /* EqualsToken */;
                    case 62 /* greaterThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        pos++;
                        return token = 27 /* GreaterThanToken */;
                    case 63 /* question */:
                        pos++;
                        return token = 53 /* QuestionToken */;
                    case 91 /* openBracket */:
                        pos++;
                        return token = 19 /* OpenBracketToken */;
                    case 93 /* closeBracket */:
                        pos++;
                        return token = 20 /* CloseBracketToken */;
                    case 94 /* caret */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 68 /* CaretEqualsToken */;
                        }
                        pos++;
                        return token = 48 /* CaretToken */;
                    case 123 /* openBrace */:
                        pos++;
                        return token = 15 /* OpenBraceToken */;
                    case 124 /* bar */:
                        if (text.charCodeAt(pos + 1) === 124 /* bar */) {
                            return pos += 2, token = 52 /* BarBarToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 67 /* BarEqualsToken */;
                        }
                        pos++;
                        return token = 47 /* BarToken */;
                    case 125 /* closeBrace */:
                        pos++;
                        return token = 16 /* CloseBraceToken */;
                    case 126 /* tilde */:
                        pos++;
                        return token = 50 /* TildeToken */;
                    case 64 /* at */:
                        pos++;
                        return token = 55 /* 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 === 27 /* 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 = 65 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
                        }
                        return pos += 2, token = 45 /* GreaterThanGreaterThanGreaterThanToken */;
                    }
                    if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                        return pos += 2, token = 64 /* GreaterThanGreaterThanEqualsToken */;
                    }
                    pos++;
                    return token = 44 /* GreaterThanGreaterThanToken */;
                }
                if (text.charCodeAt(pos) === 61 /* equals */) {
                    pos++;
                    return token = 29 /* GreaterThanEqualsToken */;
                }
            }
            return token;
        }
        function reScanSlashToken() {
            if (token === 39 /* SlashToken */ || token === 61 /* 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 = 10 /* RegularExpressionLiteral */;
            }
            return token;
        }
        /**
         * Unconditionally back up and scan a template expression portion.
         */
        function reScanTemplateToken() {
            ts.Debug.assert(token === 16 /* 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 = 26 /* LessThanSlashToken */;
                }
                pos++;
                return token = 25 /* LessThanToken */;
            }
            if (char === 123 /* openBrace */) {
                pos++;
                return token = 15 /* OpenBraceToken */;
            }
            while (pos < end) {
                pos++;
                char = text.charCodeAt(pos);
                if ((char === 123 /* openBrace */) || (char === 60 /* lessThan */)) {
                    break;
                }
            }
            return token = 244 /* 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 scanJSDocToken() {
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            startPos = pos;
            // Eat leading whitespace
            var ch = text.charCodeAt(pos);
            while (pos < end) {
                ch = text.charCodeAt(pos);
                if (isWhiteSpaceSingleLine(ch)) {
                    pos++;
                }
                else {
                    break;
                }
            }
            tokenPos = pos;
            switch (ch) {
                case 64 /* at */:
                    return pos += 1, token = 55 /* AtToken */;
                case 10 /* lineFeed */:
                case 13 /* carriageReturn */:
                    return pos += 1, token = 4 /* NewLineTrivia */;
                case 42 /* asterisk */:
                    return pos += 1, token = 37 /* AsteriskToken */;
                case 123 /* openBrace */:
                    return pos += 1, token = 15 /* OpenBraceToken */;
                case 125 /* closeBrace */:
                    return pos += 1, token = 16 /* CloseBraceToken */;
                case 91 /* openBracket */:
                    return pos += 1, token = 19 /* OpenBracketToken */;
                case 93 /* closeBracket */:
                    return pos += 1, token = 20 /* CloseBracketToken */;
                case 61 /* equals */:
                    return pos += 1, token = 56 /* EqualsToken */;
                case 44 /* comma */:
                    return pos += 1, token = 24 /* CommaToken */;
            }
            if (isIdentifierStart(ch, 2 /* Latest */)) {
                pos++;
                while (isIdentifierPart(text.charCodeAt(pos), 2 /* Latest */) && pos < end) {
                    pos++;
                }
                return token = 69 /* 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) {
    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;
    // Pool writers to avoid needing to allocate them for every symbol we write.
    var stringWriters = [];
    function getSingleLineStringWriter() {
        if (stringWriters.length === 0) {
            var str_1 = "";
            var writeText = function (text) { return str_1 += text; };
            return {
                string: function () { return str_1; },
                writeKeyword: writeText,
                writeOperator: writeText,
                writePunctuation: writeText,
                writeSpace: writeText,
                writeStringLiteral: writeText,
                writeParameter: writeText,
                writeSymbol: writeText,
                // Completely ignore indentation for string writers.  And map newlines to
                // a single space.
                writeLine: function () { return str_1 += " "; },
                increaseIndent: function () { },
                decreaseIndent: function () { },
                clear: function () { return str_1 = ""; },
                trackSymbol: function () { },
                reportInaccessibleThisError: function () { }
            };
        }
        return stringWriters.pop();
    }
    ts.getSingleLineStringWriter = getSingleLineStringWriter;
    function releaseStringWriter(writer) {
        writer.clear();
        stringWriters.push(writer);
    }
    ts.releaseStringWriter = releaseStringWriter;
    function getFullWidth(node) {
        return node.end - node.pos;
    }
    ts.getFullWidth = getFullWidth;
    function mapIsEqualTo(map1, map2) {
        if (!map1 || !map2) {
            return map1 === map2;
        }
        return containsAll(map1, map2) && containsAll(map2, map1);
    }
    ts.mapIsEqualTo = mapIsEqualTo;
    function containsAll(map, other) {
        for (var key in map) {
            if (!ts.hasProperty(map, key)) {
                continue;
            }
            if (!ts.hasProperty(other, key) || map[key] !== other[key]) {
                return false;
            }
        }
        return true;
    }
    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 hasResolvedModule(sourceFile, moduleNameText) {
        return sourceFile.resolvedModules && ts.hasProperty(sourceFile.resolvedModules, moduleNameText);
    }
    ts.hasResolvedModule = hasResolvedModule;
    function getResolvedModule(sourceFile, moduleNameText) {
        return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
    }
    ts.getResolvedModule = getResolvedModule;
    function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
        if (!sourceFile.resolvedModules) {
            sourceFile.resolvedModules = {};
        }
        sourceFile.resolvedModules[moduleNameText] = resolvedModule;
    }
    ts.setResolvedModule = setResolvedModule;
    function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) {
        if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
            sourceFile.resolvedTypeReferenceDirectiveNames = {};
        }
        sourceFile.resolvedTypeReferenceDirectiveNames[typeReferenceDirectiveName] = resolvedTypeReferenceDirective;
    }
    ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective;
    /* @internal */
    function moduleResolutionIsEqualTo(oldResolution, newResolution) {
        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport;
    }
    ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo;
    /* @internal */
    function typeDirectiveIsEqualTo(oldResolution, newResolution) {
        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary;
    }
    ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo;
    /* @internal */
    function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) {
        if (names.length !== newResolutions.length) {
            return false;
        }
        for (var i = 0; i < names.length; i++) {
            var newResolution = newResolutions[i];
            var oldResolution = oldResolutions && ts.hasProperty(oldResolutions, names[i]) ? oldResolutions[names[i]] : undefined;
            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 & 268435456 /* ThisNodeOrAnySubNodesHasError */) !== 0;
    }
    ts.containsParseError = containsParseError;
    function aggregateChildData(node) {
        if (!(node.flags & 536870912 /* 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 & 67108864 /* ThisNodeHasError */) !== 0) ||
                ts.forEachChild(node, containsParseError);
            // If so, mark ourselves accordingly.
            if (thisNodeOrAnySubNodesHasError) {
                node.flags |= 268435456 /* 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 |= 536870912 /* HasAggregatedChildData */;
        }
    }
    function getSourceFileOfNode(node) {
        while (node && node.kind !== 256 /* SourceFile */) {
            node = node.parent;
        }
        return node;
    }
    ts.getSourceFileOfNode = getSourceFileOfNode;
    function isStatementWithLocals(node) {
        switch (node.kind) {
            case 199 /* Block */:
            case 227 /* CaseBlock */:
            case 206 /* ForStatement */:
            case 207 /* ForInStatement */:
            case 208 /* 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 getStartPosOfNode(node) {
        return node.pos;
    }
    ts.getStartPosOfNode = getStartPosOfNode;
    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) {
            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;
    function getTokenPosOfNode(node, sourceFile, includeJsDocComment) {
        // 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 (isJSDocNode(node)) {
            return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        if (includeJsDocComment && node.jsDocComments && node.jsDocComments.length > 0) {
            return getTokenPosOfNode(node.jsDocComments[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 === 282 /* SyntaxList */ && node._children.length > 0) {
            return getTokenPosOfNode(node._children[0], sourceFile, includeJsDocComment);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
    }
    ts.getTokenPosOfNode = getTokenPosOfNode;
    function isJSDocNode(node) {
        return node.kind >= 257 /* FirstJSDocNode */ && node.kind <= 281 /* LastJSDocNode */;
    }
    ts.isJSDocNode = isJSDocNode;
    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;
    // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
    function escapeIdentifier(identifier) {
        return identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier;
    }
    ts.escapeIdentifier = escapeIdentifier;
    // Remove extra underscore from escaped identifier
    function unescapeIdentifier(identifier) {
        return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
    }
    ts.unescapeIdentifier = unescapeIdentifier;
    // 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 (getCombinedNodeFlags(declaration) & 3072 /* BlockScoped */) !== 0 ||
            isCatchClauseVariableDeclaration(declaration);
    }
    ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
    function isAmbientModule(node) {
        return node && node.kind === 225 /* ModuleDeclaration */ &&
            (node.name.kind === 9 /* StringLiteral */ || isGlobalScopeAugmentation(node));
    }
    ts.isAmbientModule = isAmbientModule;
    function isShorthandAmbientModule(node) {
        // The only kind of module that can be missing a body is a shorthand ambient module.
        return node.kind === 225 /* ModuleDeclaration */ && (!node.body);
    }
    ts.isShorthandAmbientModule = isShorthandAmbientModule;
    function isBlockScopedContainerTopLevel(node) {
        return node.kind === 256 /* SourceFile */ ||
            node.kind === 225 /* ModuleDeclaration */ ||
            isFunctionLike(node) ||
            isFunctionBlock(node);
    }
    ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel;
    function isGlobalScopeAugmentation(module) {
        return !!(module.flags & 131072 /* 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 256 /* SourceFile */:
                return ts.isExternalModule(node.parent);
            case 226 /* ModuleBlock */:
                return isAmbientModule(node.parent.parent) && !ts.isExternalModule(node.parent.parent.parent);
        }
        return false;
    }
    ts.isExternalModuleAugmentation = isExternalModuleAugmentation;
    // 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 (isFunctionLike(current)) {
                return current;
            }
            switch (current.kind) {
                case 256 /* SourceFile */:
                case 227 /* CaseBlock */:
                case 252 /* CatchClause */:
                case 225 /* ModuleDeclaration */:
                case 206 /* ForStatement */:
                case 207 /* ForInStatement */:
                case 208 /* ForOfStatement */:
                    return current;
                case 199 /* Block */:
                    // function block is not considered block-scope container
                    // see comment in binder.ts: bind(...), case for SyntaxKind.Block
                    if (!isFunctionLike(current.parent)) {
                        return current;
                    }
            }
            current = current.parent;
        }
    }
    ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
    function isCatchClauseVariableDeclaration(declaration) {
        return declaration &&
            declaration.kind === 218 /* VariableDeclaration */ &&
            declaration.parent &&
            declaration.parent.kind === 252 /* CatchClause */;
    }
    ts.isCatchClauseVariableDeclaration = isCatchClauseVariableDeclaration;
    // 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 createDiagnosticForNode(node, message, arg0, arg1, arg2) {
        var sourceFile = getSourceFileOfNode(node);
        var span = getErrorSpanForNode(sourceFile, node);
        return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
    }
    ts.createDiagnosticForNode = createDiagnosticForNode;
    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 === 199 /* 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 256 /* 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 218 /* VariableDeclaration */:
            case 169 /* BindingElement */:
            case 221 /* ClassDeclaration */:
            case 192 /* ClassExpression */:
            case 222 /* InterfaceDeclaration */:
            case 225 /* ModuleDeclaration */:
            case 224 /* EnumDeclaration */:
            case 255 /* EnumMember */:
            case 220 /* FunctionDeclaration */:
            case 179 /* FunctionExpression */:
            case 147 /* MethodDeclaration */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 223 /* TypeAliasDeclaration */:
                errorNode = node.name;
                break;
            case 180 /* 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 isDeclarationFile(file) {
        return file.isDeclarationFile;
    }
    ts.isDeclarationFile = isDeclarationFile;
    function isConstEnumDeclaration(node) {
        return node.kind === 224 /* EnumDeclaration */ && isConst(node);
    }
    ts.isConstEnumDeclaration = isConstEnumDeclaration;
    function walkUpBindingElementsAndPatterns(node) {
        while (node && (node.kind === 169 /* BindingElement */ || isBindingPattern(node))) {
            node = node.parent;
        }
        return node;
    }
    // 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 === 218 /* VariableDeclaration */) {
            node = node.parent;
        }
        if (node && node.kind === 219 /* VariableDeclarationList */) {
            flags |= node.flags;
            node = node.parent;
        }
        if (node && node.kind === 200 /* VariableStatement */) {
            flags |= node.flags;
        }
        return flags;
    }
    ts.getCombinedNodeFlags = getCombinedNodeFlags;
    function isConst(node) {
        return !!(getCombinedNodeFlags(node) & 2048 /* Const */);
    }
    ts.isConst = isConst;
    function isLet(node) {
        return !!(getCombinedNodeFlags(node) & 1024 /* Let */);
    }
    ts.isLet = isLet;
    function isSuperCallExpression(n) {
        return n.kind === 174 /* CallExpression */ && n.expression.kind === 95 /* SuperKeyword */;
    }
    ts.isSuperCallExpression = isSuperCallExpression;
    function isPrologueDirective(node) {
        return node.kind === 202 /* ExpressionStatement */ && node.expression.kind === 9 /* StringLiteral */;
    }
    ts.isPrologueDirective = isPrologueDirective;
    function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
        return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
    }
    ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
    function getLeadingCommentRangesOfNodeFromText(node, text) {
        return ts.getLeadingCommentRanges(text, node.pos);
    }
    ts.getLeadingCommentRangesOfNodeFromText = getLeadingCommentRangesOfNodeFromText;
    function getJsDocComments(node, sourceFileOfNode) {
        return getJsDocCommentsFromText(node, sourceFileOfNode.text);
    }
    ts.getJsDocComments = getJsDocComments;
    function getJsDocCommentsFromText(node, text) {
        var commentRanges = (node.kind === 142 /* Parameter */ ||
            node.kind === 141 /* TypeParameter */ ||
            node.kind === 179 /* FunctionExpression */ ||
            node.kind === 180 /* ArrowFunction */) ?
            ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
            getLeadingCommentRangesOfNodeFromText(node, text);
        return ts.filter(commentRanges, isJsDocComment);
        function isJsDocComment(comment) {
            // True if the comment starts with '/**' but not if it is '/**/'
            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
        }
    }
    ts.getJsDocCommentsFromText = getJsDocCommentsFromText;
    ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)('|")(.+?)\2.*?\/>/;
    ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    function isTypeNode(node) {
        if (154 /* FirstTypeNode */ <= node.kind && node.kind <= 166 /* LastTypeNode */) {
            return true;
        }
        switch (node.kind) {
            case 117 /* AnyKeyword */:
            case 130 /* NumberKeyword */:
            case 132 /* StringKeyword */:
            case 120 /* BooleanKeyword */:
            case 133 /* SymbolKeyword */:
            case 135 /* UndefinedKeyword */:
            case 127 /* NeverKeyword */:
                return true;
            case 103 /* VoidKeyword */:
                return node.parent.kind !== 183 /* VoidExpression */;
            case 194 /* 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 69 /* Identifier */:
                // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
                if (node.parent.kind === 139 /* QualifiedName */ && node.parent.right === node) {
                    node = node.parent;
                }
                else if (node.parent.kind === 172 /* 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 === 69 /* Identifier */ || node.kind === 139 /* QualifiedName */ || node.kind === 172 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'.");
            case 139 /* QualifiedName */:
            case 172 /* PropertyAccessExpression */:
            case 97 /* ThisKeyword */:
                var parent_1 = node.parent;
                if (parent_1.kind === 158 /* TypeQuery */) {
                    return false;
                }
                // Do not recursively call isTypeNode on the parent. In the example:
                //
                //     let a: A.B.C;
                //
                // Calling isTypeNode would consider the qualified name A.B a type node. Only C or
                // A.B.C is a type node.
                if (154 /* FirstTypeNode */ <= parent_1.kind && parent_1.kind <= 166 /* LastTypeNode */) {
                    return true;
                }
                switch (parent_1.kind) {
                    case 194 /* ExpressionWithTypeArguments */:
                        return !isExpressionWithTypeArgumentsInClassExtendsClause(parent_1);
                    case 141 /* TypeParameter */:
                        return node === parent_1.constraint;
                    case 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                    case 142 /* Parameter */:
                    case 218 /* VariableDeclaration */:
                        return node === parent_1.type;
                    case 220 /* FunctionDeclaration */:
                    case 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                    case 148 /* Constructor */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        return node === parent_1.type;
                    case 151 /* CallSignature */:
                    case 152 /* ConstructSignature */:
                    case 153 /* IndexSignature */:
                        return node === parent_1.type;
                    case 177 /* TypeAssertionExpression */:
                        return node === parent_1.type;
                    case 174 /* CallExpression */:
                    case 175 /* NewExpression */:
                        return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0;
                    case 176 /* TaggedTemplateExpression */:
                        // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
                        return false;
                }
        }
        return false;
    }
    ts.isTypeNode = isTypeNode;
    // 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 211 /* ReturnStatement */:
                    return visitor(node);
                case 227 /* CaseBlock */:
                case 199 /* Block */:
                case 203 /* IfStatement */:
                case 204 /* DoStatement */:
                case 205 /* WhileStatement */:
                case 206 /* ForStatement */:
                case 207 /* ForInStatement */:
                case 208 /* ForOfStatement */:
                case 212 /* WithStatement */:
                case 213 /* SwitchStatement */:
                case 249 /* CaseClause */:
                case 250 /* DefaultClause */:
                case 214 /* LabeledStatement */:
                case 216 /* TryStatement */:
                case 252 /* CatchClause */:
                    return ts.forEachChild(node, traverse);
            }
        }
    }
    ts.forEachReturnStatement = forEachReturnStatement;
    function forEachYieldExpression(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 190 /* YieldExpression */:
                    visitor(node);
                    var operand = node.expression;
                    if (operand) {
                        traverse(operand);
                    }
                case 224 /* EnumDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 225 /* ModuleDeclaration */:
                case 223 /* TypeAliasDeclaration */:
                case 221 /* ClassDeclaration */:
                case 192 /* 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 (isFunctionLike(node)) {
                        var name_5 = node.name;
                        if (name_5 && name_5.kind === 140 /* 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_5.expression);
                            return;
                        }
                    }
                    else if (!isTypeNode(node)) {
                        // This is the general case, which should include mostly expressions and statements.
                        // Also includes NodeArrays.
                        ts.forEachChild(node, traverse);
                    }
            }
        }
    }
    ts.forEachYieldExpression = forEachYieldExpression;
    function isVariableLike(node) {
        if (node) {
            switch (node.kind) {
                case 169 /* BindingElement */:
                case 255 /* EnumMember */:
                case 142 /* Parameter */:
                case 253 /* PropertyAssignment */:
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 254 /* ShorthandPropertyAssignment */:
                case 218 /* VariableDeclaration */:
                    return true;
            }
        }
        return false;
    }
    ts.isVariableLike = isVariableLike;
    function isAccessor(node) {
        return node && (node.kind === 149 /* GetAccessor */ || node.kind === 150 /* SetAccessor */);
    }
    ts.isAccessor = isAccessor;
    function isClassLike(node) {
        return node && (node.kind === 221 /* ClassDeclaration */ || node.kind === 192 /* ClassExpression */);
    }
    ts.isClassLike = isClassLike;
    function isFunctionLike(node) {
        return node && isFunctionLikeKind(node.kind);
    }
    ts.isFunctionLike = isFunctionLike;
    function isFunctionLikeKind(kind) {
        switch (kind) {
            case 148 /* Constructor */:
            case 179 /* FunctionExpression */:
            case 220 /* FunctionDeclaration */:
            case 180 /* ArrowFunction */:
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 151 /* CallSignature */:
            case 152 /* ConstructSignature */:
            case 153 /* IndexSignature */:
            case 156 /* FunctionType */:
            case 157 /* ConstructorType */:
                return true;
        }
        return false;
    }
    ts.isFunctionLikeKind = isFunctionLikeKind;
    function introducesArgumentsExoticObject(node) {
        switch (node.kind) {
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
            case 148 /* Constructor */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 220 /* FunctionDeclaration */:
            case 179 /* FunctionExpression */:
                return true;
        }
        return false;
    }
    ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
    function isIterationStatement(node, lookInLabeledStatements) {
        switch (node.kind) {
            case 206 /* ForStatement */:
            case 207 /* ForInStatement */:
            case 208 /* ForOfStatement */:
            case 204 /* DoStatement */:
            case 205 /* WhileStatement */:
                return true;
            case 214 /* LabeledStatement */:
                return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
        }
        return false;
    }
    ts.isIterationStatement = isIterationStatement;
    function isFunctionBlock(node) {
        return node && node.kind === 199 /* Block */ && isFunctionLike(node.parent);
    }
    ts.isFunctionBlock = isFunctionBlock;
    function isObjectLiteralMethod(node) {
        return node && node.kind === 147 /* MethodDeclaration */ && node.parent.kind === 171 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralMethod = isObjectLiteralMethod;
    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 getContainingFunction(node) {
        while (true) {
            node = node.parent;
            if (!node || isFunctionLike(node)) {
                return node;
            }
        }
    }
    ts.getContainingFunction = getContainingFunction;
    function getContainingClass(node) {
        while (true) {
            node = node.parent;
            if (!node || isClassLike(node)) {
                return node;
            }
        }
    }
    ts.getContainingClass = getContainingClass;
    function getThisContainer(node, includeArrowFunctions) {
        while (true) {
            node = node.parent;
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 140 /* 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 (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 143 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 142 /* Parameter */ && 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 (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 180 /* ArrowFunction */:
                    if (!includeArrowFunctions) {
                        continue;
                    }
                // Fall through
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 225 /* ModuleDeclaration */:
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 148 /* Constructor */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 151 /* CallSignature */:
                case 152 /* ConstructSignature */:
                case 153 /* IndexSignature */:
                case 224 /* EnumDeclaration */:
                case 256 /* SourceFile */:
                    return node;
            }
        }
    }
    ts.getThisContainer = getThisContainer;
    /**
      * Given an super call\property node returns a closest node where either
      * - super call\property 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.
      * - node is arrow function (so caller might need to call getSuperContainer in case it needs to climb higher)
      * - super call\property is definitely illegal in the node (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 140 /* ComputedPropertyName */:
                    node = node.parent;
                    break;
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    if (!stopOnFunctions) {
                        continue;
                    }
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 148 /* Constructor */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                    return node;
                case 143 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 142 /* Parameter */ && 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 (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 === 179 /* FunctionExpression */ || func.kind === 180 /* ArrowFunction */) {
            var prev = func;
            var parent_2 = func.parent;
            while (parent_2.kind === 178 /* ParenthesizedExpression */) {
                prev = parent_2;
                parent_2 = parent_2.parent;
            }
            if (parent_2.kind === 174 /* CallExpression */ && parent_2.expression === prev) {
                return parent_2;
            }
        }
    }
    ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression;
    /**
     * Determines whether a node is a property or element access expression for super.
     */
    function isSuperPropertyOrElementAccess(node) {
        return (node.kind === 172 /* PropertyAccessExpression */
            || node.kind === 173 /* ElementAccessExpression */)
            && node.expression.kind === 95 /* SuperKeyword */;
    }
    ts.isSuperPropertyOrElementAccess = isSuperPropertyOrElementAccess;
    function getEntityNameFromTypeNode(node) {
        if (node) {
            switch (node.kind) {
                case 155 /* TypeReference */:
                    return node.typeName;
                case 194 /* ExpressionWithTypeArguments */:
                    return node.expression;
                case 69 /* Identifier */:
                case 139 /* QualifiedName */:
                    return node;
            }
        }
        return undefined;
    }
    ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
    function getInvokedExpression(node) {
        if (node.kind === 176 /* TaggedTemplateExpression */) {
            return node.tag;
        }
        // Will either be a CallExpression, NewExpression, or Decorator.
        return node.expression;
    }
    ts.getInvokedExpression = getInvokedExpression;
    function nodeCanBeDecorated(node) {
        switch (node.kind) {
            case 221 /* ClassDeclaration */:
                // classes are valid targets
                return true;
            case 145 /* PropertyDeclaration */:
                // property declarations are valid if their parent is a class declaration.
                return node.parent.kind === 221 /* ClassDeclaration */;
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 147 /* 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 === 221 /* ClassDeclaration */;
            case 142 /* 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 === 148 /* Constructor */
                        || node.parent.kind === 147 /* MethodDeclaration */
                        || node.parent.kind === 150 /* SetAccessor */)
                    && node.parent.parent.kind === 221 /* ClassDeclaration */;
        }
        return false;
    }
    ts.nodeCanBeDecorated = nodeCanBeDecorated;
    function nodeIsDecorated(node) {
        return node.decorators !== undefined
            && nodeCanBeDecorated(node);
    }
    ts.nodeIsDecorated = nodeIsDecorated;
    function isPropertyAccessExpression(node) {
        return node.kind === 172 /* PropertyAccessExpression */;
    }
    ts.isPropertyAccessExpression = isPropertyAccessExpression;
    function isElementAccessExpression(node) {
        return node.kind === 173 /* ElementAccessExpression */;
    }
    ts.isElementAccessExpression = isElementAccessExpression;
    function isJSXTagName(node) {
        var parent = node.parent;
        if (parent.kind === 243 /* JsxOpeningElement */ ||
            parent.kind === 242 /* JsxSelfClosingElement */ ||
            parent.kind === 245 /* JsxClosingElement */) {
            return parent.tagName === node;
        }
        return false;
    }
    ts.isJSXTagName = isJSXTagName;
    function isExpression(node) {
        switch (node.kind) {
            case 97 /* ThisKeyword */:
            case 95 /* SuperKeyword */:
            case 93 /* NullKeyword */:
            case 99 /* TrueKeyword */:
            case 84 /* FalseKeyword */:
            case 10 /* RegularExpressionLiteral */:
            case 170 /* ArrayLiteralExpression */:
            case 171 /* ObjectLiteralExpression */:
            case 172 /* PropertyAccessExpression */:
            case 173 /* ElementAccessExpression */:
            case 174 /* CallExpression */:
            case 175 /* NewExpression */:
            case 176 /* TaggedTemplateExpression */:
            case 195 /* AsExpression */:
            case 177 /* TypeAssertionExpression */:
            case 196 /* NonNullExpression */:
            case 178 /* ParenthesizedExpression */:
            case 179 /* FunctionExpression */:
            case 192 /* ClassExpression */:
            case 180 /* ArrowFunction */:
            case 183 /* VoidExpression */:
            case 181 /* DeleteExpression */:
            case 182 /* TypeOfExpression */:
            case 185 /* PrefixUnaryExpression */:
            case 186 /* PostfixUnaryExpression */:
            case 187 /* BinaryExpression */:
            case 188 /* ConditionalExpression */:
            case 191 /* SpreadElementExpression */:
            case 189 /* TemplateExpression */:
            case 11 /* NoSubstitutionTemplateLiteral */:
            case 193 /* OmittedExpression */:
            case 241 /* JsxElement */:
            case 242 /* JsxSelfClosingElement */:
            case 190 /* YieldExpression */:
            case 184 /* AwaitExpression */:
                return true;
            case 139 /* QualifiedName */:
                while (node.parent.kind === 139 /* QualifiedName */) {
                    node = node.parent;
                }
                return node.parent.kind === 158 /* TypeQuery */ || isJSXTagName(node);
            case 69 /* Identifier */:
                if (node.parent.kind === 158 /* TypeQuery */ || isJSXTagName(node)) {
                    return true;
                }
            // fall through
            case 8 /* NumericLiteral */:
            case 9 /* StringLiteral */:
            case 97 /* ThisKeyword */:
                var parent_3 = node.parent;
                switch (parent_3.kind) {
                    case 218 /* VariableDeclaration */:
                    case 142 /* Parameter */:
                    case 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                    case 255 /* EnumMember */:
                    case 253 /* PropertyAssignment */:
                    case 169 /* BindingElement */:
                        return parent_3.initializer === node;
                    case 202 /* ExpressionStatement */:
                    case 203 /* IfStatement */:
                    case 204 /* DoStatement */:
                    case 205 /* WhileStatement */:
                    case 211 /* ReturnStatement */:
                    case 212 /* WithStatement */:
                    case 213 /* SwitchStatement */:
                    case 249 /* CaseClause */:
                    case 215 /* ThrowStatement */:
                    case 213 /* SwitchStatement */:
                        return parent_3.expression === node;
                    case 206 /* ForStatement */:
                        var forStatement = parent_3;
                        return (forStatement.initializer === node && forStatement.initializer.kind !== 219 /* VariableDeclarationList */) ||
                            forStatement.condition === node ||
                            forStatement.incrementor === node;
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                        var forInStatement = parent_3;
                        return (forInStatement.initializer === node && forInStatement.initializer.kind !== 219 /* VariableDeclarationList */) ||
                            forInStatement.expression === node;
                    case 177 /* TypeAssertionExpression */:
                    case 195 /* AsExpression */:
                        return node === parent_3.expression;
                    case 197 /* TemplateSpan */:
                        return node === parent_3.expression;
                    case 140 /* ComputedPropertyName */:
                        return node === parent_3.expression;
                    case 143 /* Decorator */:
                    case 248 /* JsxExpression */:
                    case 247 /* JsxSpreadAttribute */:
                        return true;
                    case 194 /* ExpressionWithTypeArguments */:
                        return parent_3.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_3);
                    default:
                        if (isExpression(parent_3)) {
                            return true;
                        }
                }
        }
        return false;
    }
    ts.isExpression = isExpression;
    function isExternalModuleNameRelative(moduleName) {
        // TypeScript 1.0 spec (April 2014): 11.2.1
        // An external module name is "relative" if the first term is "." or "..".
        return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
    }
    ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
    function isInstantiatedModule(node, preserveConstEnums) {
        var moduleState = ts.getModuleInstanceState(node);
        return moduleState === 1 /* Instantiated */ ||
            (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */);
    }
    ts.isInstantiatedModule = isInstantiatedModule;
    function isExternalModuleImportEqualsDeclaration(node) {
        return node.kind === 229 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 240 /* 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 === 229 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 240 /* ExternalModuleReference */;
    }
    ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
    function isSourceFileJavaScript(file) {
        return isInJavaScriptFile(file);
    }
    ts.isSourceFileJavaScript = isSourceFileJavaScript;
    function isInJavaScriptFile(node) {
        return node && !!(node.flags & 134217728 /* JavaScriptFile */);
    }
    ts.isInJavaScriptFile = isInJavaScriptFile;
    /**
     * Returns true if the node is a CallExpression to the identifier 'require' with
     * exactly one argument.
     * This function does not test if the node is in a JavaScript file or not.
    */
    function isRequireCall(expression, checkArgumentIsStringLiteral) {
        // of the form 'require("name")'
        var isRequire = expression.kind === 174 /* CallExpression */ &&
            expression.expression.kind === 69 /* Identifier */ &&
            expression.expression.text === "require" &&
            expression.arguments.length === 1;
        return isRequire && (!checkArgumentIsStringLiteral || expression.arguments[0].kind === 9 /* StringLiteral */);
    }
    ts.isRequireCall = isRequireCall;
    function isSingleOrDoubleQuote(charCode) {
        return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */;
    }
    ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote;
    /**
     * 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 isDeclarationOfFunctionExpression(s) {
        if (s.valueDeclaration && s.valueDeclaration.kind === 218 /* VariableDeclaration */) {
            var declaration = s.valueDeclaration;
            return declaration.initializer && declaration.initializer.kind === 179 /* FunctionExpression */;
        }
        return false;
    }
    ts.isDeclarationOfFunctionExpression = isDeclarationOfFunctionExpression;
    /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
    /// assignments we treat as special in the binder
    function getSpecialPropertyAssignmentKind(expression) {
        if (!isInJavaScriptFile(expression)) {
            return 0 /* None */;
        }
        if (expression.kind !== 187 /* BinaryExpression */) {
            return 0 /* None */;
        }
        var expr = expression;
        if (expr.operatorToken.kind !== 56 /* EqualsToken */ || expr.left.kind !== 172 /* PropertyAccessExpression */) {
            return 0 /* None */;
        }
        var lhs = expr.left;
        if (lhs.expression.kind === 69 /* Identifier */) {
            var lhsId = lhs.expression;
            if (lhsId.text === "exports") {
                // exports.name = expr
                return 1 /* ExportsProperty */;
            }
            else if (lhsId.text === "module" && lhs.name.text === "exports") {
                // module.exports = expr
                return 2 /* ModuleExports */;
            }
        }
        else if (lhs.expression.kind === 97 /* ThisKeyword */) {
            return 4 /* ThisProperty */;
        }
        else if (lhs.expression.kind === 172 /* PropertyAccessExpression */) {
            // chained dot, e.g. x.y.z = expr; this var is the 'x.y' part
            var innerPropertyAccess = lhs.expression;
            if (innerPropertyAccess.expression.kind === 69 /* Identifier */) {
                // module.exports.name = expr
                var innerPropertyAccessIdentifier = innerPropertyAccess.expression;
                if (innerPropertyAccessIdentifier.text === "module" && innerPropertyAccess.name.text === "exports") {
                    return 1 /* ExportsProperty */;
                }
                if (innerPropertyAccess.name.text === "prototype") {
                    return 3 /* PrototypeProperty */;
                }
            }
        }
        return 0 /* None */;
    }
    ts.getSpecialPropertyAssignmentKind = getSpecialPropertyAssignmentKind;
    function getExternalModuleName(node) {
        if (node.kind === 230 /* ImportDeclaration */) {
            return node.moduleSpecifier;
        }
        if (node.kind === 229 /* ImportEqualsDeclaration */) {
            var reference = node.moduleReference;
            if (reference.kind === 240 /* ExternalModuleReference */) {
                return reference.expression;
            }
        }
        if (node.kind === 236 /* ExportDeclaration */) {
            return node.moduleSpecifier;
        }
        if (node.kind === 225 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */) {
            return node.name;
        }
    }
    ts.getExternalModuleName = getExternalModuleName;
    function hasQuestionToken(node) {
        if (node) {
            switch (node.kind) {
                case 142 /* Parameter */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 254 /* ShorthandPropertyAssignment */:
                case 253 /* PropertyAssignment */:
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                    return node.questionToken !== undefined;
            }
        }
        return false;
    }
    ts.hasQuestionToken = hasQuestionToken;
    function isJSDocConstructSignature(node) {
        return node.kind === 269 /* JSDocFunctionType */ &&
            node.parameters.length > 0 &&
            node.parameters[0].type.kind === 271 /* JSDocConstructorType */;
    }
    ts.isJSDocConstructSignature = isJSDocConstructSignature;
    function getJSDocTag(node, kind, checkParentVariableStatement) {
        if (!node) {
            return undefined;
        }
        var jsDocComments = getJSDocComments(node, checkParentVariableStatement);
        if (!jsDocComments) {
            return undefined;
        }
        for (var _i = 0, jsDocComments_1 = jsDocComments; _i < jsDocComments_1.length; _i++) {
            var jsDocComment = jsDocComments_1[_i];
            for (var _a = 0, _b = jsDocComment.tags; _a < _b.length; _a++) {
                var tag = _b[_a];
                if (tag.kind === kind) {
                    return tag;
                }
            }
        }
    }
    function getJSDocComments(node, checkParentVariableStatement) {
        if (node.jsDocComments) {
            return node.jsDocComments;
        }
        // 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 (checkParentVariableStatement) {
            var isInitializerOfVariableDeclarationInStatement = node.parent.kind === 218 /* VariableDeclaration */ &&
                node.parent.initializer === node &&
                node.parent.parent.parent.kind === 200 /* VariableStatement */;
            var variableStatementNode = isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : undefined;
            if (variableStatementNode) {
                return variableStatementNode.jsDocComments;
            }
            // Also recognize when the node is the RHS of an assignment expression
            var parent_4 = node.parent;
            var isSourceOfAssignmentExpressionStatement = parent_4 && parent_4.parent &&
                parent_4.kind === 187 /* BinaryExpression */ &&
                parent_4.operatorToken.kind === 56 /* EqualsToken */ &&
                parent_4.parent.kind === 202 /* ExpressionStatement */;
            if (isSourceOfAssignmentExpressionStatement) {
                return parent_4.parent.jsDocComments;
            }
            var isPropertyAssignmentExpression = parent_4 && parent_4.kind === 253 /* PropertyAssignment */;
            if (isPropertyAssignmentExpression) {
                return parent_4.jsDocComments;
            }
        }
        return undefined;
    }
    function getJSDocTypeTag(node) {
        return getJSDocTag(node, 277 /* JSDocTypeTag */, /*checkParentVariableStatement*/ false);
    }
    ts.getJSDocTypeTag = getJSDocTypeTag;
    function getJSDocReturnTag(node) {
        return getJSDocTag(node, 276 /* JSDocReturnTag */, /*checkParentVariableStatement*/ true);
    }
    ts.getJSDocReturnTag = getJSDocReturnTag;
    function getJSDocTemplateTag(node) {
        return getJSDocTag(node, 278 /* JSDocTemplateTag */, /*checkParentVariableStatement*/ false);
    }
    ts.getJSDocTemplateTag = getJSDocTemplateTag;
    function getCorrespondingJSDocParameterTag(parameter) {
        if (parameter.name && parameter.name.kind === 69 /* Identifier */) {
            // If it's a parameter, see if the parent has a jsdoc comment with an @param
            // annotation.
            var parameterName = parameter.name.text;
            var jsDocComments = getJSDocComments(parameter.parent, /*checkParentVariableStatement*/ true);
            if (jsDocComments) {
                for (var _i = 0, jsDocComments_2 = jsDocComments; _i < jsDocComments_2.length; _i++) {
                    var jsDocComment = jsDocComments_2[_i];
                    for (var _a = 0, _b = jsDocComment.tags; _a < _b.length; _a++) {
                        var tag = _b[_a];
                        if (tag.kind === 275 /* JSDocParameterTag */) {
                            var parameterTag = tag;
                            var name_6 = parameterTag.preParameterName || parameterTag.postParameterName;
                            if (name_6.text === parameterName) {
                                return parameterTag;
                            }
                        }
                    }
                }
            }
        }
        return undefined;
    }
    ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag;
    function hasRestParameter(s) {
        return isRestParameter(ts.lastOrUndefined(s.parameters));
    }
    ts.hasRestParameter = hasRestParameter;
    function hasDeclaredRestParameter(s) {
        return isDeclaredRestParam(ts.lastOrUndefined(s.parameters));
    }
    ts.hasDeclaredRestParameter = hasDeclaredRestParameter;
    function isRestParameter(node) {
        if (node && (node.flags & 134217728 /* JavaScriptFile */)) {
            if (node.type && node.type.kind === 270 /* JSDocVariadicType */) {
                return true;
            }
            var paramTag = getCorrespondingJSDocParameterTag(node);
            if (paramTag && paramTag.typeExpression) {
                return paramTag.typeExpression.type.kind === 270 /* JSDocVariadicType */;
            }
        }
        return isDeclaredRestParam(node);
    }
    ts.isRestParameter = isRestParameter;
    function isDeclaredRestParam(node) {
        return node && node.dotDotDotToken !== undefined;
    }
    ts.isDeclaredRestParam = isDeclaredRestParam;
    function isLiteralKind(kind) {
        return 8 /* FirstLiteralToken */ <= kind && kind <= 11 /* LastLiteralToken */;
    }
    ts.isLiteralKind = isLiteralKind;
    function isTextualLiteralKind(kind) {
        return kind === 9 /* StringLiteral */ || kind === 11 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isTextualLiteralKind = isTextualLiteralKind;
    function isTemplateLiteralKind(kind) {
        return 11 /* FirstTemplateToken */ <= kind && kind <= 14 /* LastTemplateToken */;
    }
    ts.isTemplateLiteralKind = isTemplateLiteralKind;
    function isBindingPattern(node) {
        return !!node && (node.kind === 168 /* ArrayBindingPattern */ || node.kind === 167 /* ObjectBindingPattern */);
    }
    ts.isBindingPattern = isBindingPattern;
    // 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', '[{ p: a}] = xxx'.
    function isAssignmentTarget(node) {
        while (node.parent.kind === 178 /* ParenthesizedExpression */) {
            node = node.parent;
        }
        while (true) {
            var parent_5 = node.parent;
            if (parent_5.kind === 170 /* ArrayLiteralExpression */ || parent_5.kind === 191 /* SpreadElementExpression */) {
                node = parent_5;
                continue;
            }
            if (parent_5.kind === 253 /* PropertyAssignment */ || parent_5.kind === 254 /* ShorthandPropertyAssignment */) {
                node = parent_5.parent;
                continue;
            }
            return parent_5.kind === 187 /* BinaryExpression */ &&
                parent_5.operatorToken.kind === 56 /* EqualsToken */ &&
                parent_5.left === node ||
                (parent_5.kind === 207 /* ForInStatement */ || parent_5.kind === 208 /* ForOfStatement */) &&
                    parent_5.initializer === node;
        }
    }
    ts.isAssignmentTarget = isAssignmentTarget;
    function isNodeDescendentOf(node, ancestor) {
        while (node) {
            if (node === ancestor)
                return true;
            node = node.parent;
        }
        return false;
    }
    ts.isNodeDescendentOf = isNodeDescendentOf;
    function isInAmbientContext(node) {
        while (node) {
            if (node.flags & 2 /* Ambient */ || (node.kind === 256 /* SourceFile */ && node.isDeclarationFile)) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    ts.isInAmbientContext = isInAmbientContext;
    function isDeclaration(node) {
        switch (node.kind) {
            case 180 /* ArrowFunction */:
            case 169 /* BindingElement */:
            case 221 /* ClassDeclaration */:
            case 192 /* ClassExpression */:
            case 148 /* Constructor */:
            case 224 /* EnumDeclaration */:
            case 255 /* EnumMember */:
            case 238 /* ExportSpecifier */:
            case 220 /* FunctionDeclaration */:
            case 179 /* FunctionExpression */:
            case 149 /* GetAccessor */:
            case 231 /* ImportClause */:
            case 229 /* ImportEqualsDeclaration */:
            case 234 /* ImportSpecifier */:
            case 222 /* InterfaceDeclaration */:
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
            case 225 /* ModuleDeclaration */:
            case 232 /* NamespaceImport */:
            case 142 /* Parameter */:
            case 253 /* PropertyAssignment */:
            case 145 /* PropertyDeclaration */:
            case 144 /* PropertySignature */:
            case 150 /* SetAccessor */:
            case 254 /* ShorthandPropertyAssignment */:
            case 223 /* TypeAliasDeclaration */:
            case 141 /* TypeParameter */:
            case 218 /* VariableDeclaration */:
            case 279 /* JSDocTypedefTag */:
                return true;
        }
        return false;
    }
    ts.isDeclaration = isDeclaration;
    function isStatement(n) {
        switch (n.kind) {
            case 210 /* BreakStatement */:
            case 209 /* ContinueStatement */:
            case 217 /* DebuggerStatement */:
            case 204 /* DoStatement */:
            case 202 /* ExpressionStatement */:
            case 201 /* EmptyStatement */:
            case 207 /* ForInStatement */:
            case 208 /* ForOfStatement */:
            case 206 /* ForStatement */:
            case 203 /* IfStatement */:
            case 214 /* LabeledStatement */:
            case 211 /* ReturnStatement */:
            case 213 /* SwitchStatement */:
            case 215 /* ThrowStatement */:
            case 216 /* TryStatement */:
            case 200 /* VariableStatement */:
            case 205 /* WhileStatement */:
            case 212 /* WithStatement */:
            case 235 /* ExportAssignment */:
                return true;
            default:
                return false;
        }
    }
    ts.isStatement = isStatement;
    function isClassElement(n) {
        switch (n.kind) {
            case 148 /* Constructor */:
            case 145 /* PropertyDeclaration */:
            case 147 /* MethodDeclaration */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 146 /* MethodSignature */:
            case 153 /* IndexSignature */:
                return true;
            default:
                return false;
        }
    }
    ts.isClassElement = isClassElement;
    // True if the given identifier, string literal, or number literal is the name of a declaration node
    function isDeclarationName(name) {
        if (name.kind !== 69 /* Identifier */ && name.kind !== 9 /* StringLiteral */ && name.kind !== 8 /* NumericLiteral */) {
            return false;
        }
        var parent = name.parent;
        if (parent.kind === 234 /* ImportSpecifier */ || parent.kind === 238 /* ExportSpecifier */) {
            if (parent.propertyName) {
                return true;
            }
        }
        if (isDeclaration(parent)) {
            return parent.name === name;
        }
        return false;
    }
    ts.isDeclarationName = isDeclarationName;
    function isLiteralComputedPropertyDeclarationName(node) {
        return (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) &&
            node.parent.kind === 140 /* ComputedPropertyName */ &&
            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 145 /* PropertyDeclaration */:
            case 144 /* PropertySignature */:
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 255 /* EnumMember */:
            case 253 /* PropertyAssignment */:
            case 172 /* PropertyAccessExpression */:
                // Name in member declaration or property name in property access
                return parent.name === node;
            case 139 /* QualifiedName */:
                // Name on right hand side of dot in a type query
                if (parent.right === node) {
                    while (parent.kind === 139 /* QualifiedName */) {
                        parent = parent.parent;
                    }
                    return parent.kind === 158 /* TypeQuery */;
                }
                return false;
            case 169 /* BindingElement */:
            case 234 /* ImportSpecifier */:
                // Property name in binding element or import specifier
                return parent.propertyName === node;
            case 238 /* ExportSpecifier */:
                // Any name in an export specifier
                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 = ...
    // export default ...
    function isAliasSymbolDeclaration(node) {
        return node.kind === 229 /* ImportEqualsDeclaration */ ||
            node.kind === 228 /* NamespaceExportDeclaration */ ||
            node.kind === 231 /* ImportClause */ && !!node.name ||
            node.kind === 232 /* NamespaceImport */ ||
            node.kind === 234 /* ImportSpecifier */ ||
            node.kind === 238 /* ExportSpecifier */ ||
            node.kind === 235 /* ExportAssignment */ && node.expression.kind === 69 /* Identifier */;
    }
    ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
    function getClassExtendsHeritageClauseElement(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 83 /* ExtendsKeyword */);
        return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
    }
    ts.getClassExtendsHeritageClauseElement = getClassExtendsHeritageClauseElement;
    function getClassImplementsHeritageClauseElements(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 106 /* ImplementsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements;
    function getInterfaceBaseTypeNodes(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 83 /* 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 = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/gim;
        if (simpleReferenceRegEx.test(comment)) {
            if (isNoDefaultLibRegEx.test(comment)) {
                return {
                    isNoDefaultLib: true
                };
            }
            else {
                var refMatchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment);
                var refLibResult = !refMatchResult && ts.fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment);
                if (refMatchResult || refLibResult) {
                    var start = commentRange.pos;
                    var end = commentRange.end;
                    return {
                        fileReference: {
                            pos: start,
                            end: end,
                            fileName: (refMatchResult || refLibResult)[3]
                        },
                        isNoDefaultLib: false,
                        isTypeReferenceDirective: !!refLibResult
                    };
                }
                return {
                    diagnosticMessage: ts.Diagnostics.Invalid_reference_directive_syntax,
                    isNoDefaultLib: false
                };
            }
        }
        return undefined;
    }
    ts.getFileReferenceFromReferencePath = getFileReferenceFromReferencePath;
    function isKeyword(token) {
        return 70 /* FirstKeyword */ <= token && token <= 138 /* LastKeyword */;
    }
    ts.isKeyword = isKeyword;
    function isTrivia(token) {
        return 2 /* FirstTriviaToken */ <= token && token <= 7 /* LastTriviaToken */;
    }
    ts.isTrivia = isTrivia;
    function isAsyncFunctionLike(node) {
        return isFunctionLike(node) && (node.flags & 256 /* Async */) !== 0 && !isAccessor(node);
    }
    ts.isAsyncFunctionLike = isAsyncFunctionLike;
    function isStringOrNumericLiteral(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) {
        return declaration.name && isDynamicName(declaration.name);
    }
    ts.hasDynamicName = hasDynamicName;
    function isDynamicName(name) {
        return name.kind === 140 /* ComputedPropertyName */ &&
            !isStringOrNumericLiteral(name.expression.kind) &&
            !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 isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
    }
    ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
    function getPropertyNameForPropertyNameNode(name) {
        if (name.kind === 69 /* Identifier */ || name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */ || name.kind === 142 /* Parameter */) {
            return name.text;
        }
        if (name.kind === 140 /* ComputedPropertyName */) {
            var nameExpression = name.expression;
            if (isWellKnownSymbolSyntactically(nameExpression)) {
                var rightHandSideName = nameExpression.name.text;
                return getPropertyNameForKnownSymbolName(rightHandSideName);
            }
            else if (nameExpression.kind === 9 /* StringLiteral */ || nameExpression.kind === 8 /* NumericLiteral */) {
                return nameExpression.text;
            }
        }
        return undefined;
    }
    ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
    function getPropertyNameForKnownSymbolName(symbolName) {
        return "__@" + symbolName;
    }
    ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
    /**
     * Includes the word "Symbol" with unicode escapes
     */
    function isESSymbolIdentifier(node) {
        return node.kind === 69 /* Identifier */ && node.text === "Symbol";
    }
    ts.isESSymbolIdentifier = isESSymbolIdentifier;
    function isModifierKind(token) {
        switch (token) {
            case 115 /* AbstractKeyword */:
            case 118 /* AsyncKeyword */:
            case 74 /* ConstKeyword */:
            case 122 /* DeclareKeyword */:
            case 77 /* DefaultKeyword */:
            case 82 /* ExportKeyword */:
            case 112 /* PublicKeyword */:
            case 110 /* PrivateKeyword */:
            case 111 /* ProtectedKeyword */:
            case 128 /* ReadonlyKeyword */:
            case 113 /* StaticKeyword */:
                return true;
        }
        return false;
    }
    ts.isModifierKind = isModifierKind;
    function isParameterDeclaration(node) {
        var root = getRootDeclaration(node);
        return root.kind === 142 /* Parameter */;
    }
    ts.isParameterDeclaration = isParameterDeclaration;
    function getRootDeclaration(node) {
        while (node.kind === 169 /* BindingElement */) {
            node = node.parent.parent;
        }
        return node;
    }
    ts.getRootDeclaration = getRootDeclaration;
    function nodeStartsNewLexicalEnvironment(n) {
        return isFunctionLike(n) || n.kind === 225 /* ModuleDeclaration */ || n.kind === 256 /* SourceFile */;
    }
    ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
    /**
     * Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
     * properties are excluded by default, and can be provided via the "location", "flags", and
     * "parent" parameters.
     * @param node The node to clone.
     * @param location An optional TextRange to use to supply the new position.
     * @param flags The NodeFlags to use for the cloned node.
     * @param parent The parent for the new node.
     */
    function cloneNode(node, location, flags, parent) {
        // 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).
        var clone = location !== undefined
            ? ts.createNode(node.kind, location.pos, location.end)
            : createSynthesizedNode(node.kind);
        for (var key in node) {
            if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
                continue;
            }
            clone[key] = node[key];
        }
        if (flags !== undefined) {
            clone.flags = flags;
        }
        if (parent !== undefined) {
            clone.parent = parent;
        }
        return clone;
    }
    ts.cloneNode = cloneNode;
    /**
     * Creates a deep clone of an EntityName, with new parent pointers.
     * @param node The EntityName to clone.
     * @param parent The parent for the cloned node.
     */
    function cloneEntityName(node, parent) {
        var clone = cloneNode(node, node, node.flags, parent);
        if (isQualifiedName(clone)) {
            var left = clone.left, right = clone.right;
            clone.left = cloneEntityName(left, clone);
            clone.right = cloneNode(right, right, right.flags, parent);
        }
        return clone;
    }
    ts.cloneEntityName = cloneEntityName;
    function isQualifiedName(node) {
        return node.kind === 139 /* QualifiedName */;
    }
    ts.isQualifiedName = isQualifiedName;
    function nodeIsSynthesized(node) {
        return node.pos === -1;
    }
    ts.nodeIsSynthesized = nodeIsSynthesized;
    function createSynthesizedNode(kind, startsOnNewLine) {
        var node = ts.createNode(kind, /* pos */ -1, /* end */ -1);
        node.startsOnNewLine = startsOnNewLine;
        return node;
    }
    ts.createSynthesizedNode = createSynthesizedNode;
    function createSynthesizedNodeArray() {
        var array = [];
        array.pos = -1;
        array.end = -1;
        return array;
    }
    ts.createSynthesizedNodeArray = createSynthesizedNodeArray;
    function createDiagnosticCollection() {
        var nonFileDiagnostics = [];
        var fileDiagnostics = {};
        var diagnosticsModified = false;
        var modificationCount = 0;
        return {
            add: add,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getDiagnostics: getDiagnostics,
            getModificationCount: getModificationCount,
            reattachFileDiagnostics: reattachFileDiagnostics
        };
        function getModificationCount() {
            return modificationCount;
        }
        function reattachFileDiagnostics(newFile) {
            if (!ts.hasProperty(fileDiagnostics, newFile.fileName)) {
                return;
            }
            for (var _i = 0, _a = fileDiagnostics[newFile.fileName]; _i < _a.length; _i++) {
                var diagnostic = _a[_i];
                diagnostic.file = newFile;
            }
        }
        function add(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics[diagnostic.file.fileName];
                if (!diagnostics) {
                    diagnostics = [];
                    fileDiagnostics[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[fileName] || [];
            }
            var allDiagnostics = [];
            function pushDiagnostic(d) {
                allDiagnostics.push(d);
            }
            ts.forEach(nonFileDiagnostics, pushDiagnostic);
            for (var key in fileDiagnostics) {
                if (ts.hasProperty(fileDiagnostics, key)) {
                    ts.forEach(fileDiagnostics[key], pushDiagnostic);
                }
            }
            return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        }
        function sortAndDeduplicate() {
            if (!diagnosticsModified) {
                return;
            }
            diagnosticsModified = false;
            nonFileDiagnostics = ts.sortAndDeduplicateDiagnostics(nonFileDiagnostics);
            for (var key in fileDiagnostics) {
                if (ts.hasProperty(fileDiagnostics, key)) {
                    fileDiagnostics[key] = ts.sortAndDeduplicateDiagnostics(fileDiagnostics[key]);
                }
            }
        }
    }
    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 escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var escapedCharsMap = {
        "\0": "\\0",
        "\t": "\\t",
        "\v": "\\v",
        "\f": "\\f",
        "\b": "\\b",
        "\r": "\\r",
        "\n": "\\n",
        "\\": "\\\\",
        "\"": "\\\"",
        "\u2028": "\\u2028",
        "\u2029": "\\u2029",
        "\u0085": "\\u0085" // nextLine
    };
    /**
     * 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) {
        s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s;
        return s;
        function getReplacement(c) {
            return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
        }
    }
    ts.escapeString = escapeString;
    function isIntrinsicJsxName(name) {
        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 escapeNonAsciiCharacters(s) {
        // 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.escapeNonAsciiCharacters = escapeNonAsciiCharacters;
    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; },
            reset: reset
        };
    }
    ts.createTextWriter = createTextWriter;
    /**
     * 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
        if (options.declaration) {
            var path = outputDir
                ? getSourceFilePathInNewDir(sourceFile, host, outputDir)
                : sourceFile.fileName;
            return ts.removeFileExtension(path) + ".d.ts";
        }
    }
    ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath;
    function getEmitScriptTarget(compilerOptions) {
        return compilerOptions.target || 0 /* ES3 */;
    }
    ts.getEmitScriptTarget = getEmitScriptTarget;
    function getEmitModuleKind(compilerOptions) {
        return typeof compilerOptions.module === "number" ?
            compilerOptions.module :
            getEmitScriptTarget(compilerOptions) === 2 /* ES6 */ ? ts.ModuleKind.ES6 : ts.ModuleKind.CommonJS;
    }
    ts.getEmitModuleKind = getEmitModuleKind;
    function forEachExpectedEmitFile(host, action, targetSourceFile) {
        var options = host.getCompilerOptions();
        // Emit on each source file
        if (options.outFile || options.out) {
            onBundledEmit(host);
        }
        else {
            var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
            for (var _i = 0, sourceFiles_1 = sourceFiles; _i < sourceFiles_1.length; _i++) {
                var sourceFile = sourceFiles_1[_i];
                // Don't emit if source file is a declaration file, or was located under node_modules
                if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) {
                    onSingleFileEmit(host, sourceFile);
                }
            }
        }
        function onSingleFileEmit(host, sourceFile) {
            // 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
            var extension = ".js";
            if (options.jsx === 1 /* Preserve */) {
                if (isSourceFileJavaScript(sourceFile)) {
                    if (ts.fileExtensionIs(sourceFile.fileName, ".jsx")) {
                        extension = ".jsx";
                    }
                }
                else if (sourceFile.languageVariant === 1 /* JSX */) {
                    // TypeScript source file preserving JSX syntax
                    extension = ".jsx";
                }
            }
            var jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, extension);
            var emitFileNames = {
                jsFilePath: jsFilePath,
                sourceMapFilePath: getSourceMapFilePath(jsFilePath, options),
                declarationFilePath: !isSourceFileJavaScript(sourceFile) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined
            };
            action(emitFileNames, [sourceFile], /*isBundledEmit*/ false);
        }
        function onBundledEmit(host) {
            // Can emit only sources that are not declaration file and are either non module code or module with
            // --module or --target es6 specified. Files included by searching under node_modules are also not emitted.
            var bundledSources = ts.filter(host.getSourceFiles(), function (sourceFile) { return !isDeclarationFile(sourceFile) &&
                !host.isSourceFileFromExternalLibrary(sourceFile) &&
                (!ts.isExternalModule(sourceFile) ||
                    !!getEmitModuleKind(options)); });
            if (bundledSources.length) {
                var jsFilePath = options.outFile || options.out;
                var emitFileNames = {
                    jsFilePath: jsFilePath,
                    sourceMapFilePath: getSourceMapFilePath(jsFilePath, options),
                    declarationFilePath: options.declaration ? ts.removeFileExtension(jsFilePath) + ".d.ts" : undefined
                };
                action(emitFileNames, bundledSources, /*isBundledEmit*/ true);
            }
        }
        function getSourceMapFilePath(jsFilePath, options) {
            return options.sourceMap ? jsFilePath + ".map" : undefined;
        }
    }
    ts.forEachExpectedEmitFile = forEachExpectedEmitFile;
    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 === 148 /* Constructor */ && nodeIsPresent(member.body)) {
                return member;
            }
        });
    }
    ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
    function getSetAccessorTypeAnnotationNode(accessor) {
        if (accessor && accessor.parameters.length > 0) {
            var hasThis = accessor.parameters.length === 2 &&
                accessor.parameters[0].name.kind === 69 /* Identifier */ &&
                accessor.parameters[0].name.originalKeywordKind === 97 /* ThisKeyword */;
            return accessor.parameters[hasThis ? 1 : 0].type;
        }
    }
    ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
    function getAllAccessorDeclarations(declarations, accessor) {
        var firstAccessor;
        var secondAccessor;
        var getAccessor;
        var setAccessor;
        if (hasDynamicName(accessor)) {
            firstAccessor = accessor;
            if (accessor.kind === 149 /* GetAccessor */) {
                getAccessor = accessor;
            }
            else if (accessor.kind === 150 /* SetAccessor */) {
                setAccessor = accessor;
            }
            else {
                ts.Debug.fail("Accessor has wrong kind");
            }
        }
        else {
            ts.forEach(declarations, function (member) {
                if ((member.kind === 149 /* GetAccessor */ || member.kind === 150 /* SetAccessor */)
                    && (member.flags & 32 /* Static */) === (accessor.flags & 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 === 149 /* GetAccessor */ && !getAccessor) {
                            getAccessor = member;
                        }
                        if (member.kind === 150 /* SetAccessor */ && !setAccessor) {
                            setAccessor = member;
                        }
                    }
                }
            });
        }
        return {
            firstAccessor: firstAccessor,
            secondAccessor: secondAccessor,
            getAccessor: getAccessor,
            setAccessor: setAccessor
        };
    }
    ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
    function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
        // If the leading comments start on different line than the start of node, write new line
        if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos &&
            getLineOfLocalPositionFromLineMap(lineMap, node.pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
    function emitComments(text, lineMap, writer, comments, trailingSeparator, newLine, writeComment) {
        var emitLeadingSpace = !trailingSeparator;
        ts.forEach(comments, function (comment) {
            if (emitLeadingSpace) {
                writer.write(" ");
                emitLeadingSpace = false;
            }
            writeComment(text, lineMap, writer, comment, newLine);
            if (comment.hasTrailingNewLine) {
                writer.writeLine();
            }
            else if (trailingSeparator) {
                writer.write(" ");
            }
            else {
                // Emit leading space to separate comment during next comment emit
                emitLeadingSpace = true;
            }
        });
    }
    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), isPinnedComment);
            }
        }
        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, /*trailingSeparator*/ true, newLine, writeComment);
                    currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end };
                }
            }
        }
        return currentDetachedCommentInfo;
        function isPinnedComment(comment) {
            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
        }
    }
    ts.emitDetachedComments = emitDetachedComments;
    function writeCommentRange(text, lineMap, writer, comment, newLine) {
        if (text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
            var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, comment.pos);
            var lineCount = lineMap.length;
            var firstCommentLineIndent = void 0;
            for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
                var nextLineStart = (currentLine + 1) === lineCount
                    ? text.length + 1
                    : lineMap[currentLine + 1];
                if (pos !== comment.pos) {
                    // 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], comment.pos);
                    }
                    // 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, comment, writer, newLine, pos, nextLineStart);
                pos = nextLineStart;
            }
        }
        else {
            // Single line comment of style //....
            writer.write(text.substring(comment.pos, comment.end));
        }
    }
    ts.writeCommentRange = writeCommentRange;
    function writeTrimmedCurrentLine(text, comment, writer, newLine, pos, nextLineStart) {
        var end = Math.min(comment.end, 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 !== comment.end) {
                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 modifierToFlag(token) {
        switch (token) {
            case 113 /* StaticKeyword */: return 32 /* Static */;
            case 112 /* PublicKeyword */: return 4 /* Public */;
            case 111 /* ProtectedKeyword */: return 16 /* Protected */;
            case 110 /* PrivateKeyword */: return 8 /* Private */;
            case 115 /* AbstractKeyword */: return 128 /* Abstract */;
            case 82 /* ExportKeyword */: return 1 /* Export */;
            case 122 /* DeclareKeyword */: return 2 /* Ambient */;
            case 74 /* ConstKeyword */: return 2048 /* Const */;
            case 77 /* DefaultKeyword */: return 512 /* Default */;
            case 118 /* AsyncKeyword */: return 256 /* Async */;
            case 128 /* ReadonlyKeyword */: return 64 /* Readonly */;
        }
        return 0;
    }
    ts.modifierToFlag = modifierToFlag;
    function isLeftHandSideExpression(expr) {
        if (expr) {
            switch (expr.kind) {
                case 172 /* PropertyAccessExpression */:
                case 173 /* ElementAccessExpression */:
                case 175 /* NewExpression */:
                case 174 /* CallExpression */:
                case 196 /* NonNullExpression */:
                case 241 /* JsxElement */:
                case 242 /* JsxSelfClosingElement */:
                case 176 /* TaggedTemplateExpression */:
                case 170 /* ArrayLiteralExpression */:
                case 178 /* ParenthesizedExpression */:
                case 171 /* ObjectLiteralExpression */:
                case 192 /* ClassExpression */:
                case 179 /* FunctionExpression */:
                case 69 /* Identifier */:
                case 10 /* RegularExpressionLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* StringLiteral */:
                case 11 /* NoSubstitutionTemplateLiteral */:
                case 189 /* TemplateExpression */:
                case 84 /* FalseKeyword */:
                case 93 /* NullKeyword */:
                case 97 /* ThisKeyword */:
                case 99 /* TrueKeyword */:
                case 95 /* SuperKeyword */:
                    return true;
            }
        }
        return false;
    }
    ts.isLeftHandSideExpression = isLeftHandSideExpression;
    function isAssignmentOperator(token) {
        return token >= 56 /* FirstAssignment */ && token <= 68 /* LastAssignment */;
    }
    ts.isAssignmentOperator = isAssignmentOperator;
    function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
        return node.kind === 194 /* ExpressionWithTypeArguments */ &&
            node.parent.token === 83 /* ExtendsKeyword */ &&
            isClassLike(node.parent.parent);
    }
    ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
    // Returns false if this heritage clause element's expression contains something unsupported
    // (i.e. not a name or dotted name).
    function isSupportedExpressionWithTypeArguments(node) {
        return isSupportedExpressionWithTypeArgumentsRest(node.expression);
    }
    ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments;
    function isSupportedExpressionWithTypeArgumentsRest(node) {
        if (node.kind === 69 /* Identifier */) {
            return true;
        }
        else if (isPropertyAccessExpression(node)) {
            return isSupportedExpressionWithTypeArgumentsRest(node.expression);
        }
        else {
            return false;
        }
    }
    function isRightSideOfQualifiedNameOrPropertyAccess(node) {
        return (node.parent.kind === 139 /* QualifiedName */ && node.parent.right === node) ||
            (node.parent.kind === 172 /* PropertyAccessExpression */ && node.parent.name === node);
    }
    ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
    function isEmptyObjectLiteralOrArrayLiteral(expression) {
        var kind = expression.kind;
        if (kind === 171 /* ObjectLiteralExpression */) {
            return expression.properties.length === 0;
        }
        if (kind === 170 /* ArrayLiteralExpression */) {
            return expression.elements.length === 0;
        }
        return false;
    }
    ts.isEmptyObjectLiteralOrArrayLiteral = isEmptyObjectLiteralOrArrayLiteral;
    function getLocalSymbolForExportDefault(symbol) {
        return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 512 /* Default */) ? symbol.valueDeclaration.localSymbol : undefined;
    }
    ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
    function hasJavaScriptFileExtension(fileName) {
        return ts.forEach(ts.supportedJavascriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension;
    function hasTypeScriptFileExtension(fileName) {
        return ts.forEach(ts.supportedTypeScriptExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension;
    /**
     * 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;
    }
    /**
     * Serialize an object graph into a JSON string. This is intended only for use on an acyclic graph
     * as the fallback implementation does not check for circular references by default.
     */
    ts.stringify = typeof JSON !== "undefined" && JSON.stringify
        ? JSON.stringify
        : stringifyFallback;
    /**
     * Serialize an object graph into a JSON string.
     */
    function stringifyFallback(value) {
        // JSON.stringify returns `undefined` here, instead of the string "undefined".
        return value === undefined ? undefined : stringifyValue(value);
    }
    function stringifyValue(value) {
        return typeof value === "string" ? "\"" + escapeString(value) + "\""
            : typeof value === "number" ? isFinite(value) ? String(value) : "null"
                : typeof value === "boolean" ? value ? "true" : "false"
                    : typeof value === "object" && value ? ts.isArray(value) ? cycleCheck(stringifyArray, value) : cycleCheck(stringifyObject, value)
                        : "null";
    }
    function cycleCheck(cb, value) {
        ts.Debug.assert(!value.hasOwnProperty("__cycle"), "Converting circular structure to JSON");
        value.__cycle = true;
        var result = cb(value);
        delete value.__cycle;
        return result;
    }
    function stringifyArray(value) {
        return "[" + ts.reduceLeft(value, stringifyElement, "") + "]";
    }
    function stringifyElement(memo, value) {
        return (memo ? memo + "," : memo) + stringifyValue(value);
    }
    function stringifyObject(value) {
        return "{" + ts.reduceProperties(value, stringifyProperty, "") + "}";
    }
    function stringifyProperty(memo, value, key) {
        return value === undefined || typeof value === "function" || key === "__cycle" ? memo
            : (memo ? memo + "," : memo) + ("\"" + escapeString(key) + "\":" + stringifyValue(value));
    }
    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;
    function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
        return !ts.isRootedDiskPath(absoluteOrRelativePath)
            ? absoluteOrRelativePath
            : ts.getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /* isAbsolutePathAnUrl */ false);
    }
    ts.convertToRelativePath = convertToRelativePath;
    var carriageReturnLineFeed = "\r\n";
    var lineFeed = "\n";
    function getNewLineCharacter(options) {
        if (options.newLine === 0 /* CarriageReturnLineFeed */) {
            return carriageReturnLineFeed;
        }
        else if (options.newLine === 1 /* LineFeed */) {
            return lineFeed;
        }
        else if (ts.sys) {
            return ts.sys.newLine;
        }
        return carriageReturnLineFeed;
    }
    ts.getNewLineCharacter = getNewLineCharacter;
    function isWatchSet(options) {
        // Firefox has Object.prototype.watch
        return options.watch && options.hasOwnProperty("watch");
    }
    ts.isWatchSet = isWatchSet;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function getDefaultLibFileName(options) {
        return options.target === 2 /* ES6 */ ? "lib.es6.d.ts" : "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 === 141 /* TypeParameter */) {
            for (var current = d; current; current = current.parent) {
                if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 222 /* InterfaceDeclaration */) {
                    return current;
                }
            }
        }
    }
    ts.getTypeParameterOwner = getTypeParameterOwner;
    function isParameterPropertyDeclaration(node) {
        return node.flags & 92 /* ParameterPropertyModifier */ && node.parent.kind === 148 /* Constructor */ && ts.isClassLike(node.parent.parent);
    }
    ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration;
    function startsWith(str, prefix) {
        return str.lastIndexOf(prefix, 0) === 0;
    }
    ts.startsWith = startsWith;
    function endsWith(str, suffix) {
        var expectedPos = str.length - suffix.length;
        return str.indexOf(suffix, expectedPos) === expectedPos;
    }
    ts.endsWith = endsWith;
})(ts || (ts = {}));
/// <reference path="utilities.ts"/>
/// <reference path="scanner.ts"/>
var ts;
(function (ts) {
    /* @internal */ ts.parseTime = 0;
    var NodeConstructor;
    var SourceFileConstructor;
    function createNode(kind, pos, end) {
        if (kind === 256 /* SourceFile */) {
            return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
        }
        else {
            return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
        }
    }
    ts.createNode = createNode;
    function visitNode(cbNode, node) {
        if (node) {
            return cbNode(node);
        }
    }
    function visitNodeArray(cbNodes, nodes) {
        if (nodes) {
            return cbNodes(nodes);
        }
    }
    function visitEachNode(cbNode, nodes) {
        if (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.
    function forEachChild(node, cbNode, cbNodeArray) {
        if (!node) {
            return;
        }
        // The visitXXX functions could be written as local functions that close over the cbNode and cbNodeArray
        // callback parameters, but that causes a closure allocation for each invocation with noticeable effects
        // on performance.
        var visitNodes = cbNodeArray ? visitNodeArray : visitEachNode;
        var cbNodes = cbNodeArray || cbNode;
        switch (node.kind) {
            case 139 /* QualifiedName */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.right);
            case 141 /* TypeParameter */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNode(cbNode, node.expression);
            case 254 /* ShorthandPropertyAssignment */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.equalsToken) ||
                    visitNode(cbNode, node.objectAssignmentInitializer);
            case 142 /* Parameter */:
            case 145 /* PropertyDeclaration */:
            case 144 /* PropertySignature */:
            case 253 /* PropertyAssignment */:
            case 218 /* VariableDeclaration */:
            case 169 /* BindingElement */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(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 156 /* FunctionType */:
            case 157 /* ConstructorType */:
            case 151 /* CallSignature */:
            case 152 /* ConstructSignature */:
            case 153 /* IndexSignature */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNodes(cbNodes, node.typeParameters) ||
                    visitNodes(cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
            case 148 /* Constructor */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 179 /* FunctionExpression */:
            case 220 /* FunctionDeclaration */:
            case 180 /* ArrowFunction */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNodes(cbNodes, node.typeParameters) ||
                    visitNodes(cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.equalsGreaterThanToken) ||
                    visitNode(cbNode, node.body);
            case 155 /* TypeReference */:
                return visitNode(cbNode, node.typeName) ||
                    visitNodes(cbNodes, node.typeArguments);
            case 154 /* TypePredicate */:
                return visitNode(cbNode, node.parameterName) ||
                    visitNode(cbNode, node.type);
            case 158 /* TypeQuery */:
                return visitNode(cbNode, node.exprName);
            case 159 /* TypeLiteral */:
                return visitNodes(cbNodes, node.members);
            case 160 /* ArrayType */:
                return visitNode(cbNode, node.elementType);
            case 161 /* TupleType */:
                return visitNodes(cbNodes, node.elementTypes);
            case 162 /* UnionType */:
            case 163 /* IntersectionType */:
                return visitNodes(cbNodes, node.types);
            case 164 /* ParenthesizedType */:
                return visitNode(cbNode, node.type);
            case 167 /* ObjectBindingPattern */:
            case 168 /* ArrayBindingPattern */:
                return visitNodes(cbNodes, node.elements);
            case 170 /* ArrayLiteralExpression */:
                return visitNodes(cbNodes, node.elements);
            case 171 /* ObjectLiteralExpression */:
                return visitNodes(cbNodes, node.properties);
            case 172 /* PropertyAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.name);
            case 173 /* ElementAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.argumentExpression);
            case 174 /* CallExpression */:
            case 175 /* NewExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNodes, node.typeArguments) ||
                    visitNodes(cbNodes, node.arguments);
            case 176 /* TaggedTemplateExpression */:
                return visitNode(cbNode, node.tag) ||
                    visitNode(cbNode, node.template);
            case 177 /* TypeAssertionExpression */:
                return visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.expression);
            case 178 /* ParenthesizedExpression */:
                return visitNode(cbNode, node.expression);
            case 181 /* DeleteExpression */:
                return visitNode(cbNode, node.expression);
            case 182 /* TypeOfExpression */:
                return visitNode(cbNode, node.expression);
            case 183 /* VoidExpression */:
                return visitNode(cbNode, node.expression);
            case 185 /* PrefixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 190 /* YieldExpression */:
                return visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.expression);
            case 184 /* AwaitExpression */:
                return visitNode(cbNode, node.expression);
            case 186 /* PostfixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 187 /* BinaryExpression */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.operatorToken) ||
                    visitNode(cbNode, node.right);
            case 195 /* AsExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.type);
            case 196 /* NonNullExpression */:
                return visitNode(cbNode, node.expression);
            case 188 /* ConditionalExpression */:
                return visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.whenTrue) ||
                    visitNode(cbNode, node.colonToken) ||
                    visitNode(cbNode, node.whenFalse);
            case 191 /* SpreadElementExpression */:
                return visitNode(cbNode, node.expression);
            case 199 /* Block */:
            case 226 /* ModuleBlock */:
                return visitNodes(cbNodes, node.statements);
            case 256 /* SourceFile */:
                return visitNodes(cbNodes, node.statements) ||
                    visitNode(cbNode, node.endOfFileToken);
            case 200 /* VariableStatement */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.declarationList);
            case 219 /* VariableDeclarationList */:
                return visitNodes(cbNodes, node.declarations);
            case 202 /* ExpressionStatement */:
                return visitNode(cbNode, node.expression);
            case 203 /* IfStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.thenStatement) ||
                    visitNode(cbNode, node.elseStatement);
            case 204 /* DoStatement */:
                return visitNode(cbNode, node.statement) ||
                    visitNode(cbNode, node.expression);
            case 205 /* WhileStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 206 /* ForStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.incrementor) ||
                    visitNode(cbNode, node.statement);
            case 207 /* ForInStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 208 /* ForOfStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 209 /* ContinueStatement */:
            case 210 /* BreakStatement */:
                return visitNode(cbNode, node.label);
            case 211 /* ReturnStatement */:
                return visitNode(cbNode, node.expression);
            case 212 /* WithStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 213 /* SwitchStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.caseBlock);
            case 227 /* CaseBlock */:
                return visitNodes(cbNodes, node.clauses);
            case 249 /* CaseClause */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNodes, node.statements);
            case 250 /* DefaultClause */:
                return visitNodes(cbNodes, node.statements);
            case 214 /* LabeledStatement */:
                return visitNode(cbNode, node.label) ||
                    visitNode(cbNode, node.statement);
            case 215 /* ThrowStatement */:
                return visitNode(cbNode, node.expression);
            case 216 /* TryStatement */:
                return visitNode(cbNode, node.tryBlock) ||
                    visitNode(cbNode, node.catchClause) ||
                    visitNode(cbNode, node.finallyBlock);
            case 252 /* CatchClause */:
                return visitNode(cbNode, node.variableDeclaration) ||
                    visitNode(cbNode, node.block);
            case 143 /* Decorator */:
                return visitNode(cbNode, node.expression);
            case 221 /* ClassDeclaration */:
            case 192 /* ClassExpression */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNodes, node.typeParameters) ||
                    visitNodes(cbNodes, node.heritageClauses) ||
                    visitNodes(cbNodes, node.members);
            case 222 /* InterfaceDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNodes, node.typeParameters) ||
                    visitNodes(cbNodes, node.heritageClauses) ||
                    visitNodes(cbNodes, node.members);
            case 223 /* TypeAliasDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNodes, node.typeParameters) ||
                    visitNode(cbNode, node.type);
            case 224 /* EnumDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNodes, node.members);
            case 255 /* EnumMember */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 225 /* ModuleDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.body);
            case 229 /* ImportEqualsDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.moduleReference);
            case 230 /* ImportDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.importClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 231 /* ImportClause */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.namedBindings);
            case 228 /* NamespaceExportDeclaration */:
                return visitNode(cbNode, node.name);
            case 232 /* NamespaceImport */:
                return visitNode(cbNode, node.name);
            case 233 /* NamedImports */:
            case 237 /* NamedExports */:
                return visitNodes(cbNodes, node.elements);
            case 236 /* ExportDeclaration */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.exportClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 234 /* ImportSpecifier */:
            case 238 /* ExportSpecifier */:
                return visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name);
            case 235 /* ExportAssignment */:
                return visitNodes(cbNodes, node.decorators) ||
                    visitNodes(cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.expression);
            case 189 /* TemplateExpression */:
                return visitNode(cbNode, node.head) || visitNodes(cbNodes, node.templateSpans);
            case 197 /* TemplateSpan */:
                return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal);
            case 140 /* ComputedPropertyName */:
                return visitNode(cbNode, node.expression);
            case 251 /* HeritageClause */:
                return visitNodes(cbNodes, node.types);
            case 194 /* ExpressionWithTypeArguments */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNodes, node.typeArguments);
            case 240 /* ExternalModuleReference */:
                return visitNode(cbNode, node.expression);
            case 239 /* MissingDeclaration */:
                return visitNodes(cbNodes, node.decorators);
            case 241 /* JsxElement */:
                return visitNode(cbNode, node.openingElement) ||
                    visitNodes(cbNodes, node.children) ||
                    visitNode(cbNode, node.closingElement);
            case 242 /* JsxSelfClosingElement */:
            case 243 /* JsxOpeningElement */:
                return visitNode(cbNode, node.tagName) ||
                    visitNodes(cbNodes, node.attributes);
            case 246 /* JsxAttribute */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 247 /* JsxSpreadAttribute */:
                return visitNode(cbNode, node.expression);
            case 248 /* JsxExpression */:
                return visitNode(cbNode, node.expression);
            case 245 /* JsxClosingElement */:
                return visitNode(cbNode, node.tagName);
            case 257 /* JSDocTypeExpression */:
                return visitNode(cbNode, node.type);
            case 261 /* JSDocUnionType */:
                return visitNodes(cbNodes, node.types);
            case 262 /* JSDocTupleType */:
                return visitNodes(cbNodes, node.types);
            case 260 /* JSDocArrayType */:
                return visitNode(cbNode, node.elementType);
            case 264 /* JSDocNonNullableType */:
                return visitNode(cbNode, node.type);
            case 263 /* JSDocNullableType */:
                return visitNode(cbNode, node.type);
            case 265 /* JSDocRecordType */:
                return visitNodes(cbNodes, node.members);
            case 267 /* JSDocTypeReference */:
                return visitNode(cbNode, node.name) ||
                    visitNodes(cbNodes, node.typeArguments);
            case 268 /* JSDocOptionalType */:
                return visitNode(cbNode, node.type);
            case 269 /* JSDocFunctionType */:
                return visitNodes(cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 270 /* JSDocVariadicType */:
                return visitNode(cbNode, node.type);
            case 271 /* JSDocConstructorType */:
                return visitNode(cbNode, node.type);
            case 272 /* JSDocThisType */:
                return visitNode(cbNode, node.type);
            case 266 /* JSDocRecordMember */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.type);
            case 273 /* JSDocComment */:
                return visitNodes(cbNodes, node.tags);
            case 275 /* JSDocParameterTag */:
                return visitNode(cbNode, node.preParameterName) ||
                    visitNode(cbNode, node.typeExpression) ||
                    visitNode(cbNode, node.postParameterName);
            case 276 /* JSDocReturnTag */:
                return visitNode(cbNode, node.typeExpression);
            case 277 /* JSDocTypeTag */:
                return visitNode(cbNode, node.typeExpression);
            case 278 /* JSDocTemplateTag */:
                return visitNodes(cbNodes, node.typeParameters);
            case 279 /* JSDocTypedefTag */:
                return visitNode(cbNode, node.typeExpression) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.jsDocTypeLiteral);
            case 281 /* JSDocTypeLiteral */:
                return visitNodes(cbNodes, node.jsDocPropertyTags);
            case 280 /* JSDocPropertyTag */:
                return visitNode(cbNode, node.typeExpression) ||
                    visitNode(cbNode, node.name);
        }
    }
    ts.forEachChild = forEachChild;
    function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) {
        if (setParentNodes === void 0) { setParentNodes = false; }
        var start = new Date().getTime();
        var result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
        ts.parseTime += new Date().getTime() - start;
        return result;
    }
    ts.createSourceFile = createSourceFile;
    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) {
        return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
    }
    ts.updateSourceFile = updateSourceFile;
    /* @internal */
    function parseIsolatedJSDocComment(content, start, length) {
        var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length);
        if (result && result.jsDocComment) {
            // because the jsDocComment was parsed out of the source file, it might
            // not be covered by the fixupParentReferences.
            Parser.fixupParentReferences(result.jsDocComment);
        }
        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(2 /* Latest */, /*skipTrivia*/ true);
        var disallowInAndDecoratorContext = 4194304 /* DisallowInContext */ | 16777216 /* DecoratorContext */;
        // capture constructors in 'initializeState' to avoid null checks
        var NodeConstructor;
        var SourceFileConstructor;
        var sourceFile;
        var parseDiagnostics;
        var syntaxCursor;
        var token;
        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(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind);
            var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
            clearState();
            return result;
        }
        Parser.parseSourceFile = parseSourceFile;
        function getLanguageVariant(scriptKind) {
            // .tsx and .jsx files are treated as jsx language variant.
            return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ ? 1 /* JSX */ : 0 /* Standard */;
        }
        function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind) {
            NodeConstructor = ts.objectAllocator.getNodeConstructor();
            SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
            sourceText = _sourceText;
            syntaxCursor = _syntaxCursor;
            parseDiagnostics = [];
            parsingContext = 0;
            identifiers = {};
            identifierCount = 0;
            nodeCount = 0;
            contextFlags = scriptKind === 1 /* JS */ || scriptKind === 2 /* JSX */ ? 134217728 /* 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.
            token = nextToken();
            processReferenceComments(sourceFile);
            sourceFile.statements = parseList(0 /* SourceElements */, parseStatement);
            ts.Debug.assert(token === 1 /* EndOfFileToken */);
            sourceFile.endOfFileToken = parseTokenNode();
            setExternalModuleIndicator(sourceFile);
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            return sourceFile;
        }
        function addJSDocComment(node) {
            if (contextFlags & 134217728 /* JavaScriptFile */) {
                var comments = ts.getLeadingCommentRangesOfNode(node, sourceFile);
                if (comments) {
                    for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                        var comment = comments_1[_i];
                        var jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
                        if (!jsDocComment) {
                            continue;
                        }
                        if (!node.jsDocComments) {
                            node.jsDocComments = [];
                        }
                        node.jsDocComments.push(jsDocComment);
                    }
                }
            }
            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 (n.jsDocComments) {
                        for (var _i = 0, _a = n.jsDocComments; _i < _a.length; _i++) {
                            var jsDocComment = _a[_i];
                            jsDocComment.parent = n;
                            parent = jsDocComment;
                            forEachChild(jsDocComment, 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(256 /* 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");
            sourceFile.scriptKind = scriptKind;
            return sourceFile;
        }
        function setContextFlag(val, flag) {
            if (val) {
                contextFlags |= flag;
            }
            else {
                contextFlags &= ~flag;
            }
        }
        function setDisallowInContext(val) {
            setContextFlag(val, 4194304 /* DisallowInContext */);
        }
        function setYieldContext(val) {
            setContextFlag(val, 8388608 /* YieldContext */);
        }
        function setDecoratorContext(val) {
            setContextFlag(val, 16777216 /* DecoratorContext */);
        }
        function setAwaitContext(val) {
            setContextFlag(val, 33554432 /* 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(4194304 /* DisallowInContext */, func);
        }
        function disallowInAnd(func) {
            return doInsideOfContext(4194304 /* DisallowInContext */, func);
        }
        function doInYieldContext(func) {
            return doInsideOfContext(8388608 /* YieldContext */, func);
        }
        function doInDecoratorContext(func) {
            return doInsideOfContext(16777216 /* DecoratorContext */, func);
        }
        function doInAwaitContext(func) {
            return doInsideOfContext(33554432 /* AwaitContext */, func);
        }
        function doOutsideOfAwaitContext(func) {
            return doOutsideOfContext(33554432 /* AwaitContext */, func);
        }
        function doInYieldAndAwaitContext(func) {
            return doInsideOfContext(8388608 /* YieldContext */ | 33554432 /* AwaitContext */, func);
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inYieldContext() {
            return inContext(8388608 /* YieldContext */);
        }
        function inDisallowInContext() {
            return inContext(4194304 /* DisallowInContext */);
        }
        function inDecoratorContext() {
            return inContext(16777216 /* DecoratorContext */);
        }
        function inAwaitContext() {
            return inContext(33554432 /* 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();
        }
        function getNodeEnd() {
            return scanner.getStartPos();
        }
        function nextToken() {
            return token = scanner.scan();
        }
        function reScanGreaterToken() {
            return token = scanner.reScanGreaterToken();
        }
        function reScanSlashToken() {
            return token = scanner.reScanSlashToken();
        }
        function reScanTemplateToken() {
            return token = scanner.reScanTemplateToken();
        }
        function scanJsxIdentifier() {
            return token = scanner.scanJsxIdentifier();
        }
        function scanJsxText() {
            return token = scanner.scanJsxToken();
        }
        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 = token;
            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 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) {
                token = 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 === 69 /* 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 === 114 /* 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 === 119 /* AwaitKeyword */ && inAwaitContext()) {
                return false;
            }
            return token > 105 /* 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 === 23 /* SemicolonToken */) {
                return true;
            }
            // We can parse out an optional semicolon in ASI cases in the following cases.
            return token === 16 /* CloseBraceToken */ || token === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
        }
        function parseSemicolon() {
            if (canParseSemicolon()) {
                if (token === 23 /* SemicolonToken */) {
                    // consume the semicolon if it was explicitly provided.
                    nextToken();
                }
                return true;
            }
            else {
                return parseExpected(23 /* SemicolonToken */);
            }
        }
        // note: this function creates only node
        function createNode(kind, pos) {
            nodeCount++;
            if (!(pos >= 0)) {
                pos = scanner.getStartPos();
            }
            return new NodeConstructor(kind, pos, pos);
        }
        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 |= 67108864 /* 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());
            result.text = "";
            return finishNode(result);
        }
        function internIdentifier(text) {
            text = ts.escapeIdentifier(text);
            return ts.hasProperty(identifiers, text) ? identifiers[text] : (identifiers[text] = text);
        }
        // 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(69 /* Identifier */);
                // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
                if (token !== 69 /* Identifier */) {
                    node.originalKeywordKind = token;
                }
                node.text = internIdentifier(scanner.getTokenValue());
                nextToken();
                return finishNode(node);
            }
            return createMissingNode(69 /* Identifier */, /*reportAtCurrentPosition*/ false, diagnosticMessage || ts.Diagnostics.Identifier_expected);
        }
        function parseIdentifier(diagnosticMessage) {
            return createIdentifier(isIdentifier(), diagnosticMessage);
        }
        function parseIdentifierName() {
            return createIdentifier(ts.tokenIsIdentifierOrKeyword(token));
        }
        function isLiteralPropertyName() {
            return ts.tokenIsIdentifierOrKeyword(token) ||
                token === 9 /* StringLiteral */ ||
                token === 8 /* NumericLiteral */;
        }
        function parsePropertyNameWorker(allowComputedPropertyNames) {
            if (token === 9 /* StringLiteral */ || token === 8 /* NumericLiteral */) {
                return parseLiteralNode(/*internName*/ true);
            }
            if (allowComputedPropertyNames && token === 19 /* OpenBracketToken */) {
                return parseComputedPropertyName();
            }
            return parseIdentifierName();
        }
        function parsePropertyName() {
            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
        }
        function parseSimplePropertyName() {
            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ false);
        }
        function isSimplePropertyName() {
            return token === 9 /* StringLiteral */ || token === 8 /* NumericLiteral */ || ts.tokenIsIdentifierOrKeyword(token);
        }
        function parseComputedPropertyName() {
            // PropertyName [Yield]:
            //      LiteralPropertyName
            //      ComputedPropertyName[?Yield]
            var node = createNode(140 /* ComputedPropertyName */);
            parseExpected(19 /* 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(20 /* 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 === 74 /* ConstKeyword */) {
                // 'const' is only a modifier if followed by 'enum'.
                return nextToken() === 81 /* EnumKeyword */;
            }
            if (token === 82 /* ExportKeyword */) {
                nextToken();
                if (token === 77 /* DefaultKeyword */) {
                    return lookAhead(nextTokenIsClassOrFunctionOrAsync);
                }
                return token !== 37 /* AsteriskToken */ && token !== 116 /* AsKeyword */ && token !== 15 /* OpenBraceToken */ && canFollowModifier();
            }
            if (token === 77 /* DefaultKeyword */) {
                return nextTokenIsClassOrFunctionOrAsync();
            }
            if (token === 113 /* StaticKeyword */) {
                nextToken();
                return canFollowModifier();
            }
            return nextTokenIsOnSameLineAndCanFollowModifier();
        }
        function parseAnyContextualModifier() {
            return ts.isModifierKind(token) && tryParse(nextTokenCanFollowModifier);
        }
        function canFollowModifier() {
            return token === 19 /* OpenBracketToken */
                || token === 15 /* OpenBraceToken */
                || token === 37 /* AsteriskToken */
                || token === 22 /* DotDotDotToken */
                || isLiteralPropertyName();
        }
        function nextTokenIsClassOrFunctionOrAsync() {
            nextToken();
            return token === 73 /* ClassKeyword */ || token === 87 /* FunctionKeyword */ ||
                (token === 118 /* 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 === 23 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement();
                case 2 /* SwitchClauses */:
                    return token === 71 /* CaseKeyword */ || token === 77 /* 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 === 23 /* 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 === 19 /* OpenBracketToken */ || isLiteralPropertyName();
                case 12 /* ObjectLiteralMembers */:
                    return token === 19 /* OpenBracketToken */ || token === 37 /* AsteriskToken */ || isLiteralPropertyName();
                case 9 /* ObjectBindingElements */:
                    return token === 19 /* OpenBracketToken */ || 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 === 15 /* 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 === 24 /* CommaToken */ || token === 22 /* DotDotDotToken */ || isIdentifierOrPattern();
                case 17 /* TypeParameters */:
                    return isIdentifier();
                case 11 /* ArgumentExpressions */:
                case 15 /* ArrayLiteralMembers */:
                    return token === 24 /* CommaToken */ || token === 22 /* DotDotDotToken */ || isStartOfExpression();
                case 16 /* Parameters */:
                    return isStartOfParameter();
                case 18 /* TypeArguments */:
                case 19 /* TupleElementTypes */:
                    return token === 24 /* CommaToken */ || isStartOfType();
                case 20 /* HeritageClauses */:
                    return isHeritageClause();
                case 21 /* ImportOrExportSpecifiers */:
                    return ts.tokenIsIdentifierOrKeyword(token);
                case 13 /* JsxAttributes */:
                    return ts.tokenIsIdentifierOrKeyword(token) || token === 15 /* OpenBraceToken */;
                case 14 /* JsxChildren */:
                    return true;
                case 22 /* JSDocFunctionParameters */:
                case 23 /* JSDocTypeArguments */:
                case 25 /* JSDocTupleTypes */:
                    return JSDocParser.isJSDocType();
                case 24 /* JSDocRecordMembers */:
                    return isSimplePropertyName();
            }
            ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
        }
        function isValidHeritageClauseObjectLiteral() {
            ts.Debug.assert(token === 15 /* OpenBraceToken */);
            if (nextToken() === 16 /* 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 === 24 /* CommaToken */ || next === 15 /* OpenBraceToken */ || next === 83 /* ExtendsKeyword */ || next === 106 /* ImplementsKeyword */;
            }
            return true;
        }
        function nextTokenIsIdentifier() {
            nextToken();
            return isIdentifier();
        }
        function nextTokenIsIdentifierOrKeyword() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token);
        }
        function isHeritageClauseExtendsOrImplementsKeyword() {
            if (token === 106 /* ImplementsKeyword */ ||
                token === 83 /* 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 21 /* ImportOrExportSpecifiers */:
                    return token === 16 /* CloseBraceToken */;
                case 3 /* SwitchClauseStatements */:
                    return token === 16 /* CloseBraceToken */ || token === 71 /* CaseKeyword */ || token === 77 /* DefaultKeyword */;
                case 7 /* HeritageClauseElement */:
                    return token === 15 /* OpenBraceToken */ || token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
                case 8 /* VariableDeclarations */:
                    return isVariableDeclaratorListTerminator();
                case 17 /* TypeParameters */:
                    // Tokens other than '>' are here for better error recovery
                    return token === 27 /* GreaterThanToken */ || token === 17 /* OpenParenToken */ || token === 15 /* OpenBraceToken */ || token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
                case 11 /* ArgumentExpressions */:
                    // Tokens other than ')' are here for better error recovery
                    return token === 18 /* CloseParenToken */ || token === 23 /* SemicolonToken */;
                case 15 /* ArrayLiteralMembers */:
                case 19 /* TupleElementTypes */:
                case 10 /* ArrayBindingElements */:
                    return token === 20 /* CloseBracketToken */;
                case 16 /* Parameters */:
                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
                    return token === 18 /* CloseParenToken */ || token === 20 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
                case 18 /* TypeArguments */:
                    // Tokens other than '>' are here for better error recovery
                    return token === 27 /* GreaterThanToken */ || token === 17 /* OpenParenToken */;
                case 20 /* HeritageClauses */:
                    return token === 15 /* OpenBraceToken */ || token === 16 /* CloseBraceToken */;
                case 13 /* JsxAttributes */:
                    return token === 27 /* GreaterThanToken */ || token === 39 /* SlashToken */;
                case 14 /* JsxChildren */:
                    return token === 25 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
                case 22 /* JSDocFunctionParameters */:
                    return token === 18 /* CloseParenToken */ || token === 54 /* ColonToken */ || token === 16 /* CloseBraceToken */;
                case 23 /* JSDocTypeArguments */:
                    return token === 27 /* GreaterThanToken */ || token === 16 /* CloseBraceToken */;
                case 25 /* JSDocTupleTypes */:
                    return token === 20 /* CloseBracketToken */ || token === 16 /* CloseBraceToken */;
                case 24 /* JSDocRecordMembers */:
                    return token === 16 /* CloseBraceToken */;
            }
        }
        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 === 34 /* 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 < 26 /* 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 result = [];
            result.pos = getNodePos();
            while (!isListTerminator(kind)) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var element = parseListElement(kind, parseElement);
                    result.push(element);
                    continue;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            result.end = getNodeEnd();
            parsingContext = saveParsingContext;
            return result;
        }
        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 & 197132288 /* 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);
                // 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 20 /* HeritageClauses */:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // heritage clauses.
                case 17 /* 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 19 /* 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 18 /* 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 148 /* Constructor */:
                    case 153 /* IndexSignature */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 145 /* PropertyDeclaration */:
                    case 198 /* SemicolonClassElement */:
                        return true;
                    case 147 /* 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 === 69 /* Identifier */ &&
                            methodDeclaration.name.originalKeywordKind === 121 /* ConstructorKeyword */;
                        return !nameIsConstructor;
                }
            }
            return false;
        }
        function isReusableSwitchClause(node) {
            if (node) {
                switch (node.kind) {
                    case 249 /* CaseClause */:
                    case 250 /* DefaultClause */:
                        return true;
                }
            }
            return false;
        }
        function isReusableStatement(node) {
            if (node) {
                switch (node.kind) {
                    case 220 /* FunctionDeclaration */:
                    case 200 /* VariableStatement */:
                    case 199 /* Block */:
                    case 203 /* IfStatement */:
                    case 202 /* ExpressionStatement */:
                    case 215 /* ThrowStatement */:
                    case 211 /* ReturnStatement */:
                    case 213 /* SwitchStatement */:
                    case 210 /* BreakStatement */:
                    case 209 /* ContinueStatement */:
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                    case 206 /* ForStatement */:
                    case 205 /* WhileStatement */:
                    case 212 /* WithStatement */:
                    case 201 /* EmptyStatement */:
                    case 216 /* TryStatement */:
                    case 214 /* LabeledStatement */:
                    case 204 /* DoStatement */:
                    case 217 /* DebuggerStatement */:
                    case 230 /* ImportDeclaration */:
                    case 229 /* ImportEqualsDeclaration */:
                    case 236 /* ExportDeclaration */:
                    case 235 /* ExportAssignment */:
                    case 225 /* ModuleDeclaration */:
                    case 221 /* ClassDeclaration */:
                    case 222 /* InterfaceDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 223 /* TypeAliasDeclaration */:
                        return true;
                }
            }
            return false;
        }
        function isReusableEnumMember(node) {
            return node.kind === 255 /* EnumMember */;
        }
        function isReusableTypeMember(node) {
            if (node) {
                switch (node.kind) {
                    case 152 /* ConstructSignature */:
                    case 146 /* MethodSignature */:
                    case 153 /* IndexSignature */:
                    case 144 /* PropertySignature */:
                    case 151 /* CallSignature */:
                        return true;
                }
            }
            return false;
        }
        function isReusableVariableDeclaration(node) {
            if (node.kind !== 218 /* 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 !== 142 /* 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 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 17 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
                case 18 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
                case 19 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
                case 20 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected;
                case 21 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected;
                case 13 /* JsxAttributes */: return ts.Diagnostics.Identifier_expected;
                case 14 /* JsxChildren */: return ts.Diagnostics.Identifier_expected;
                case 22 /* JSDocFunctionParameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 23 /* JSDocTypeArguments */: return ts.Diagnostics.Type_argument_expected;
                case 25 /* JSDocTupleTypes */: return ts.Diagnostics.Type_expected;
                case 24 /* JSDocRecordMembers */: return ts.Diagnostics.Property_assignment_expected;
            }
        }
        ;
        // Parses a comma-delimited list of elements
        function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var result = [];
            result.pos = getNodePos();
            var commaStart = -1; // Meaning the previous token was not a comma
            while (true) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    result.push(parseListElement(kind, parseElement));
                    commaStart = scanner.getTokenPos();
                    if (parseOptional(24 /* CommaToken */)) {
                        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(24 /* 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 === 23 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
                        nextToken();
                    }
                    continue;
                }
                if (isListTerminator(kind)) {
                    break;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            // 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;
            }
            result.end = getNodeEnd();
            parsingContext = saveParsingContext;
            return result;
        }
        function createMissingList() {
            var pos = getNodePos();
            var result = [];
            result.pos = pos;
            result.end = pos;
            return result;
        }
        function parseBracketedList(kind, parseElement, open, close) {
            if (parseExpected(open)) {
                var result = parseDelimitedList(kind, parseElement);
                parseExpected(close);
                return result;
            }
            return createMissingList();
        }
        // The allowReservedWords parameter controls whether reserved words are permitted after the first dot
        function parseEntityName(allowReservedWords, diagnosticMessage) {
            var entity = parseIdentifier(diagnosticMessage);
            while (parseOptional(21 /* DotToken */)) {
                var node = createNode(139 /* QualifiedName */, entity.pos); // !!!
                node.left = entity;
                node.right = parseRightSideOfDot(allowReservedWords);
                entity = finishNode(node);
            }
            return entity;
        }
        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(69 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
                }
            }
            return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
        }
        function parseTemplateExpression() {
            var template = createNode(189 /* TemplateExpression */);
            template.head = parseTemplateLiteralFragment();
            ts.Debug.assert(template.head.kind === 12 /* TemplateHead */, "Template head has wrong token kind");
            var templateSpans = [];
            templateSpans.pos = getNodePos();
            do {
                templateSpans.push(parseTemplateSpan());
            } while (ts.lastOrUndefined(templateSpans).literal.kind === 13 /* TemplateMiddle */);
            templateSpans.end = getNodeEnd();
            template.templateSpans = templateSpans;
            return finishNode(template);
        }
        function parseTemplateSpan() {
            var span = createNode(197 /* TemplateSpan */);
            span.expression = allowInAnd(parseExpression);
            var literal;
            if (token === 16 /* CloseBraceToken */) {
                reScanTemplateToken();
                literal = parseTemplateLiteralFragment();
            }
            else {
                literal = parseExpectedToken(14 /* TemplateTail */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(16 /* CloseBraceToken */));
            }
            span.literal = literal;
            return finishNode(span);
        }
        function parseStringLiteralTypeNode() {
            return parseLiteralLikeNode(166 /* StringLiteralType */, /*internName*/ true);
        }
        function parseLiteralNode(internName) {
            return parseLiteralLikeNode(token, internName);
        }
        function parseTemplateLiteralFragment() {
            return parseLiteralLikeNode(token, /*internName*/ false);
        }
        function parseLiteralLikeNode(kind, internName) {
            var node = createNode(kind);
            var text = scanner.getTokenValue();
            node.text = internName ? internIdentifier(text) : text;
            if (scanner.hasExtendedUnicodeEscape()) {
                node.hasExtendedUnicodeEscape = true;
            }
            if (scanner.isUnterminated()) {
                node.isUnterminated = true;
            }
            var tokenPos = scanner.getTokenPos();
            nextToken();
            finishNode(node);
            // 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 */
                && sourceText.charCodeAt(tokenPos) === 48 /* _0 */
                && ts.isOctalDigit(sourceText.charCodeAt(tokenPos + 1))) {
                node.isOctalLiteral = true;
            }
            return node;
        }
        // TYPES
        function parseTypeReference() {
            var typeName = parseEntityName(/*allowReservedWords*/ false, ts.Diagnostics.Type_expected);
            var node = createNode(155 /* TypeReference */, typeName.pos);
            node.typeName = typeName;
            if (!scanner.hasPrecedingLineBreak() && token === 25 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(18 /* TypeArguments */, parseType, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        function parseThisTypePredicate(lhs) {
            nextToken();
            var node = createNode(154 /* TypePredicate */, lhs.pos);
            node.parameterName = lhs;
            node.type = parseType();
            return finishNode(node);
        }
        function parseThisTypeNode() {
            var node = createNode(165 /* ThisType */);
            nextToken();
            return finishNode(node);
        }
        function parseTypeQuery() {
            var node = createNode(158 /* TypeQuery */);
            parseExpected(101 /* TypeOfKeyword */);
            node.exprName = parseEntityName(/*allowReservedWords*/ true);
            return finishNode(node);
        }
        function parseTypeParameter() {
            var node = createNode(141 /* TypeParameter */);
            node.name = parseIdentifier();
            if (parseOptional(83 /* 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();
                }
            }
            return finishNode(node);
        }
        function parseTypeParameters() {
            if (token === 25 /* LessThanToken */) {
                return parseBracketedList(17 /* TypeParameters */, parseTypeParameter, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
            }
        }
        function parseParameterType() {
            if (parseOptional(54 /* ColonToken */)) {
                return parseType();
            }
            return undefined;
        }
        function isStartOfParameter() {
            return token === 22 /* DotDotDotToken */ || isIdentifierOrPattern() || ts.isModifierKind(token) || token === 55 /* AtToken */ || token === 97 /* ThisKeyword */;
        }
        function setModifiers(node, modifiers) {
            if (modifiers) {
                node.flags |= modifiers.flags;
                node.modifiers = modifiers;
            }
        }
        function parseParameter() {
            var node = createNode(142 /* Parameter */);
            if (token === 97 /* ThisKeyword */) {
                node.name = createIdentifier(/*isIdentifier*/ true, undefined);
                node.type = parseParameterType();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            setModifiers(node, parseModifiers());
            node.dotDotDotToken = parseOptionalToken(22 /* DotDotDotToken */);
            // FormalParameter [Yield,Await]:
            //      BindingElement[?Yield,?Await]
            node.name = parseIdentifierOrPattern();
            if (ts.getFullWidth(node.name) === 0 && node.flags === 0 && 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(53 /* QuestionToken */);
            node.type = parseParameterType();
            node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
            // Do not check for initializers in an ambient context for parameters. This is not
            // a grammar error because the grammar allows arbitrary call signatures in
            // an ambient context.
            // It is actually not necessary for this to be an error at all. The reason is that
            // function/constructor implementations are syntactically disallowed in ambient
            // contexts. In addition, parameter initializers are semantically disallowed in
            // overload signatures. So parameter initializers are transitively disallowed in
            // ambient contexts.
            return addJSDocComment(finishNode(node));
        }
        function parseBindingElementInitializer(inParameter) {
            return inParameter ? parseParameterInitializer() : parseNonParameterInitializer();
        }
        function parseParameterInitializer() {
            return parseInitializer(/*inParameter*/ true);
        }
        function fillSignature(returnToken, yieldContext, awaitContext, requireCompleteParameterList, signature) {
            var returnTokenRequired = returnToken === 34 /* EqualsGreaterThanToken */;
            signature.typeParameters = parseTypeParameters();
            signature.parameters = parseParameterList(yieldContext, awaitContext, requireCompleteParameterList);
            if (returnTokenRequired) {
                parseExpected(returnToken);
                signature.type = parseTypeOrTypePredicate();
            }
            else if (parseOptional(returnToken)) {
                signature.type = parseTypeOrTypePredicate();
            }
        }
        function parseParameterList(yieldContext, awaitContext, requireCompleteParameterList) {
            // 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(17 /* OpenParenToken */)) {
                var savedYieldContext = inYieldContext();
                var savedAwaitContext = inAwaitContext();
                setYieldContext(yieldContext);
                setAwaitContext(awaitContext);
                var result = parseDelimitedList(16 /* Parameters */, parseParameter);
                setYieldContext(savedYieldContext);
                setAwaitContext(savedAwaitContext);
                if (!parseExpected(18 /* CloseParenToken */) && 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 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(24 /* CommaToken */)) {
                return;
            }
            // Didn't have a comma.  We must have a (possible ASI) semicolon.
            parseSemicolon();
        }
        function parseSignatureMember(kind) {
            var node = createNode(kind);
            if (kind === 152 /* ConstructSignature */) {
                parseExpected(92 /* NewKeyword */);
            }
            fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isIndexSignature() {
            if (token !== 19 /* 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 === 22 /* DotDotDotToken */ || token === 20 /* 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 === 54 /* ColonToken */ || token === 24 /* 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 !== 53 /* 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 === 54 /* ColonToken */ || token === 24 /* CommaToken */ || token === 20 /* CloseBracketToken */;
        }
        function parseIndexSignatureDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(153 /* IndexSignature */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 19 /* OpenBracketToken */, 20 /* CloseBracketToken */);
            node.type = parseTypeAnnotation();
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodSignature(fullStart, modifiers) {
            var name = parsePropertyName();
            var questionToken = parseOptionalToken(53 /* QuestionToken */);
            if (token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
                var method = createNode(146 /* MethodSignature */, fullStart);
                setModifiers(method, modifiers);
                method.name = name;
                method.questionToken = questionToken;
                // Method signatures don't exist in expression contexts.  So they have neither
                // [Yield] nor [Await]
                fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, method);
                parseTypeMemberSemicolon();
                return finishNode(method);
            }
            else {
                var property = createNode(144 /* PropertySignature */, fullStart);
                setModifiers(property, modifiers);
                property.name = name;
                property.questionToken = questionToken;
                property.type = parseTypeAnnotation();
                if (token === 56 /* 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 finishNode(property);
            }
        }
        function isTypeMemberStart() {
            var idToken;
            // Return true if we have the start of a signature member
            if (token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
                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;
                nextToken();
            }
            // Index signatures and computed property names are type members
            if (token === 19 /* OpenBracketToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers
            if (isLiteralPropertyName()) {
                idToken = token;
                nextToken();
            }
            // If we were able to get any potential identifier, check that it is
            // the start of a member declaration
            if (idToken) {
                return token === 17 /* OpenParenToken */ ||
                    token === 25 /* LessThanToken */ ||
                    token === 53 /* QuestionToken */ ||
                    token === 54 /* ColonToken */ ||
                    canParseSemicolon();
            }
            return false;
        }
        function parseTypeMember() {
            if (token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */) {
                return parseSignatureMember(151 /* CallSignature */);
            }
            if (token === 92 /* NewKeyword */ && lookAhead(isStartOfConstructSignature)) {
                return parseSignatureMember(152 /* ConstructSignature */);
            }
            var fullStart = getNodePos();
            var modifiers = parseModifiers();
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(fullStart, /*decorators*/ undefined, modifiers);
            }
            return parsePropertyOrMethodSignature(fullStart, modifiers);
        }
        function isStartOfConstructSignature() {
            nextToken();
            return token === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */;
        }
        function parseTypeLiteral() {
            var node = createNode(159 /* TypeLiteral */);
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseObjectTypeMembers() {
            var members;
            if (parseExpected(15 /* OpenBraceToken */)) {
                members = parseList(4 /* TypeMembers */, parseTypeMember);
                parseExpected(16 /* CloseBraceToken */);
            }
            else {
                members = createMissingList();
            }
            return members;
        }
        function parseTupleType() {
            var node = createNode(161 /* TupleType */);
            node.elementTypes = parseBracketedList(19 /* TupleElementTypes */, parseType, 19 /* OpenBracketToken */, 20 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseParenthesizedType() {
            var node = createNode(164 /* ParenthesizedType */);
            parseExpected(17 /* OpenParenToken */);
            node.type = parseType();
            parseExpected(18 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseFunctionOrConstructorType(kind) {
            var node = createNode(kind);
            if (kind === 157 /* ConstructorType */) {
                parseExpected(92 /* NewKeyword */);
            }
            fillSignature(34 /* EqualsGreaterThanToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
            return finishNode(node);
        }
        function parseKeywordAndNoDot() {
            var node = parseTokenNode();
            return token === 21 /* DotToken */ ? undefined : node;
        }
        function parseNonArrayType() {
            switch (token) {
                case 117 /* AnyKeyword */:
                case 132 /* StringKeyword */:
                case 130 /* NumberKeyword */:
                case 120 /* BooleanKeyword */:
                case 133 /* SymbolKeyword */:
                case 135 /* UndefinedKeyword */:
                case 127 /* NeverKeyword */:
                    // If these are followed by a dot, then parse these out as a dotted type reference instead.
                    var node = tryParse(parseKeywordAndNoDot);
                    return node || parseTypeReference();
                case 9 /* StringLiteral */:
                    return parseStringLiteralTypeNode();
                case 103 /* VoidKeyword */:
                case 93 /* NullKeyword */:
                    return parseTokenNode();
                case 97 /* ThisKeyword */: {
                    var thisKeyword = parseThisTypeNode();
                    if (token === 124 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                        return parseThisTypePredicate(thisKeyword);
                    }
                    else {
                        return thisKeyword;
                    }
                }
                case 101 /* TypeOfKeyword */:
                    return parseTypeQuery();
                case 15 /* OpenBraceToken */:
                    return parseTypeLiteral();
                case 19 /* OpenBracketToken */:
                    return parseTupleType();
                case 17 /* OpenParenToken */:
                    return parseParenthesizedType();
                default:
                    return parseTypeReference();
            }
        }
        function isStartOfType() {
            switch (token) {
                case 117 /* AnyKeyword */:
                case 132 /* StringKeyword */:
                case 130 /* NumberKeyword */:
                case 120 /* BooleanKeyword */:
                case 133 /* SymbolKeyword */:
                case 103 /* VoidKeyword */:
                case 135 /* UndefinedKeyword */:
                case 93 /* NullKeyword */:
                case 97 /* ThisKeyword */:
                case 101 /* TypeOfKeyword */:
                case 127 /* NeverKeyword */:
                case 15 /* OpenBraceToken */:
                case 19 /* OpenBracketToken */:
                case 25 /* LessThanToken */:
                case 92 /* NewKeyword */:
                case 9 /* StringLiteral */:
                    return true;
                case 17 /* 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 lookAhead(isStartOfParenthesizedOrFunctionType);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfParenthesizedOrFunctionType() {
            nextToken();
            return token === 18 /* CloseParenToken */ || isStartOfParameter() || isStartOfType();
        }
        function parseArrayTypeOrHigher() {
            var type = parseNonArrayType();
            while (!scanner.hasPrecedingLineBreak() && parseOptional(19 /* OpenBracketToken */)) {
                parseExpected(20 /* CloseBracketToken */);
                var node = createNode(160 /* ArrayType */, type.pos);
                node.elementType = type;
                type = finishNode(node);
            }
            return type;
        }
        function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
            var type = parseConstituentType();
            if (token === operator) {
                var types = [type];
                types.pos = type.pos;
                while (parseOptional(operator)) {
                    types.push(parseConstituentType());
                }
                types.end = getNodeEnd();
                var node = createNode(kind, type.pos);
                node.types = types;
                type = finishNode(node);
            }
            return type;
        }
        function parseIntersectionTypeOrHigher() {
            return parseUnionOrIntersectionType(163 /* IntersectionType */, parseArrayTypeOrHigher, 46 /* AmpersandToken */);
        }
        function parseUnionTypeOrHigher() {
            return parseUnionOrIntersectionType(162 /* UnionType */, parseIntersectionTypeOrHigher, 47 /* BarToken */);
        }
        function isStartOfFunctionType() {
            if (token === 25 /* LessThanToken */) {
                return true;
            }
            return token === 17 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType);
        }
        function skipParameterStart() {
            if (ts.isModifierKind(token)) {
                // Skip modifiers
                parseModifiers();
            }
            if (isIdentifier() || token === 97 /* ThisKeyword */) {
                nextToken();
                return true;
            }
            if (token === 19 /* OpenBracketToken */ || token === 15 /* 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 === 18 /* CloseParenToken */ || token === 22 /* 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 === 54 /* ColonToken */ || token === 24 /* CommaToken */ ||
                    token === 53 /* QuestionToken */ || token === 56 /* EqualsToken */) {
                    // ( xxx :
                    // ( xxx ,
                    // ( xxx ?
                    // ( xxx =
                    return true;
                }
                if (token === 18 /* CloseParenToken */) {
                    nextToken();
                    if (token === 34 /* EqualsGreaterThanToken */) {
                        // ( xxx ) =>
                        return true;
                    }
                }
            }
            return false;
        }
        function parseTypeOrTypePredicate() {
            var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix);
            var type = parseType();
            if (typePredicateVariable) {
                var node = createNode(154 /* TypePredicate */, typePredicateVariable.pos);
                node.parameterName = typePredicateVariable;
                node.type = type;
                return finishNode(node);
            }
            else {
                return type;
            }
        }
        function parseTypePredicatePrefix() {
            var id = parseIdentifier();
            if (token === 124 /* 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(41943040 /* TypeExcludesFlags */, parseTypeWorker);
        }
        function parseTypeWorker() {
            if (isStartOfFunctionType()) {
                return parseFunctionOrConstructorType(156 /* FunctionType */);
            }
            if (token === 92 /* NewKeyword */) {
                return parseFunctionOrConstructorType(157 /* ConstructorType */);
            }
            return parseUnionTypeOrHigher();
        }
        function parseTypeAnnotation() {
            return parseOptional(54 /* ColonToken */) ? parseType() : undefined;
        }
        // EXPRESSIONS
        function isStartOfLeftHandSideExpression() {
            switch (token) {
                case 97 /* ThisKeyword */:
                case 95 /* SuperKeyword */:
                case 93 /* NullKeyword */:
                case 99 /* TrueKeyword */:
                case 84 /* FalseKeyword */:
                case 8 /* NumericLiteral */:
                case 9 /* StringLiteral */:
                case 11 /* NoSubstitutionTemplateLiteral */:
                case 12 /* TemplateHead */:
                case 17 /* OpenParenToken */:
                case 19 /* OpenBracketToken */:
                case 15 /* OpenBraceToken */:
                case 87 /* FunctionKeyword */:
                case 73 /* ClassKeyword */:
                case 92 /* NewKeyword */:
                case 39 /* SlashToken */:
                case 61 /* SlashEqualsToken */:
                case 69 /* Identifier */:
                    return true;
                default:
                    return isIdentifier();
            }
        }
        function isStartOfExpression() {
            if (isStartOfLeftHandSideExpression()) {
                return true;
            }
            switch (token) {
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                case 50 /* TildeToken */:
                case 49 /* ExclamationToken */:
                case 78 /* DeleteKeyword */:
                case 101 /* TypeOfKeyword */:
                case 103 /* VoidKeyword */:
                case 41 /* PlusPlusToken */:
                case 42 /* MinusMinusToken */:
                case 25 /* LessThanToken */:
                case 119 /* AwaitKeyword */:
                case 114 /* 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 !== 15 /* OpenBraceToken */ &&
                token !== 87 /* FunctionKeyword */ &&
                token !== 73 /* ClassKeyword */ &&
                token !== 55 /* 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(24 /* CommaToken */))) {
                expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
            }
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return expr;
        }
        function parseInitializer(inParameter) {
            if (token !== 56 /* 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 === 15 /* 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;
                }
            }
            // Initializer[In, Yield] :
            //     = AssignmentExpression[?In, ?Yield]
            parseExpected(56 /* 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 '5').
            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 === 69 /* Identifier */ && token === 34 /* 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 === 114 /* 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(nextTokenIsIdentifierOrKeywordOrNumberOnSameLine);
            }
            return false;
        }
        function nextTokenIsIdentifierOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && isIdentifier();
        }
        function parseYieldExpression() {
            var node = createNode(190 /* 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 === 37 /* AsteriskToken */ || isStartOfExpression())) {
                node.asteriskToken = parseOptionalToken(37 /* 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 === 34 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
            var node;
            if (asyncModifier) {
                node = createNode(180 /* ArrowFunction */, asyncModifier.pos);
                setModifiers(node, asyncModifier);
            }
            else {
                node = createNode(180 /* ArrowFunction */, identifier.pos);
            }
            var parameter = createNode(142 /* Parameter */, identifier.pos);
            parameter.name = identifier;
            finishNode(parameter);
            node.parameters = [parameter];
            node.parameters.pos = parameter.pos;
            node.parameters.end = parameter.end;
            node.equalsGreaterThanToken = parseExpectedToken(34 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>");
            node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
            return 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 = !!(arrowFunction.flags & 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(34 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>");
            arrowFunction.body = (lastToken === 34 /* EqualsGreaterThanToken */ || lastToken === 15 /* OpenBraceToken */)
                ? parseArrowFunctionExpressionBody(isAsync)
                : parseIdentifier();
            return 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 === 17 /* OpenParenToken */ || token === 25 /* LessThanToken */ || token === 118 /* AsyncKeyword */) {
                return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
            }
            if (token === 34 /* 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 === 118 /* AsyncKeyword */) {
                nextToken();
                if (scanner.hasPrecedingLineBreak()) {
                    return 0 /* False */;
                }
                if (token !== 17 /* OpenParenToken */ && token !== 25 /* LessThanToken */) {
                    return 0 /* False */;
                }
            }
            var first = token;
            var second = nextToken();
            if (first === 17 /* OpenParenToken */) {
                if (second === 18 /* 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 34 /* EqualsGreaterThanToken */:
                        case 54 /* ColonToken */:
                        case 15 /* 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 === 19 /* OpenBracketToken */ || second === 15 /* OpenBraceToken */) {
                    return 2 /* Unknown */;
                }
                // Simple case: "(..."
                // This is an arrow function with a rest parameter.
                if (second === 22 /* 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() === 54 /* 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 === 25 /* 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 === 83 /* ExtendsKeyword */) {
                            var fourth = nextToken();
                            switch (fourth) {
                                case 56 /* EqualsToken */:
                                case 27 /* GreaterThanToken */:
                                    return false;
                                default:
                                    return true;
                            }
                        }
                        else if (third === 24 /* 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 === 118 /* AsyncKeyword */) {
                var isUnParenthesizedAsyncArrowFunction = lookAhead(isUnParenthesizedAsyncArrowFunctionWorker);
                if (isUnParenthesizedAsyncArrowFunction === 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 === 118 /* 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 === 34 /* EqualsGreaterThanToken */) {
                    return 0 /* False */;
                }
                // Check for un-parenthesized AsyncArrowFunction
                var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                if (!scanner.hasPrecedingLineBreak() && expr.kind === 69 /* Identifier */ && token === 34 /* EqualsGreaterThanToken */) {
                    return 1 /* True */;
                }
            }
            return 0 /* False */;
        }
        function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
            var node = createNode(180 /* ArrowFunction */);
            setModifiers(node, parseModifiersForArrowFunction());
            var isAsync = !!(node.flags & 256 /* Async */);
            // 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(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ !allowAmbiguity, 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 !== 34 /* EqualsGreaterThanToken */ && token !== 15 /* OpenBraceToken */) {
                // Returning undefined here will cause our caller to rewind to where we started from.
                return undefined;
            }
            return node;
        }
        function parseArrowFunctionExpressionBody(isAsync) {
            if (token === 15 /* OpenBraceToken */) {
                return parseFunctionBlock(/*allowYield*/ false, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
            }
            if (token !== 23 /* SemicolonToken */ &&
                token !== 87 /* FunctionKeyword */ &&
                token !== 73 /* 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 as true, parseBody will still error.
                return parseFunctionBlock(/*allowYield*/ false, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ true);
            }
            return isAsync
                ? doInAwaitContext(parseAssignmentExpressionOrHigher)
                : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
        }
        function parseConditionalExpressionRest(leftOperand) {
            // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher.
            var questionToken = parseOptionalToken(53 /* 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(188 /* ConditionalExpression */, leftOperand.pos);
            node.condition = leftOperand;
            node.questionToken = questionToken;
            node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
            node.colonToken = parseExpectedToken(54 /* ColonToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(54 /* ColonToken */));
            node.whenFalse = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseBinaryExpressionOrHigher(precedence) {
            var leftOperand = parseUnaryExpressionOrHigher();
            return parseBinaryExpressionRest(precedence, leftOperand);
        }
        function isInOrOfKeyword(t) {
            return t === 90 /* InKeyword */ || t === 138 /* 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 === 38 /* AsteriskAsteriskToken */ ?
                    newPrecedence >= precedence :
                    newPrecedence > precedence;
                if (!consumeCurrentOperator) {
                    break;
                }
                if (token === 90 /* InKeyword */ && inDisallowInContext()) {
                    break;
                }
                if (token === 116 /* 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 === 90 /* InKeyword */) {
                return false;
            }
            return getBinaryOperatorPrecedence() > 0;
        }
        function getBinaryOperatorPrecedence() {
            switch (token) {
                case 52 /* BarBarToken */:
                    return 1;
                case 51 /* AmpersandAmpersandToken */:
                    return 2;
                case 47 /* BarToken */:
                    return 3;
                case 48 /* CaretToken */:
                    return 4;
                case 46 /* AmpersandToken */:
                    return 5;
                case 30 /* EqualsEqualsToken */:
                case 31 /* ExclamationEqualsToken */:
                case 32 /* EqualsEqualsEqualsToken */:
                case 33 /* ExclamationEqualsEqualsToken */:
                    return 6;
                case 25 /* LessThanToken */:
                case 27 /* GreaterThanToken */:
                case 28 /* LessThanEqualsToken */:
                case 29 /* GreaterThanEqualsToken */:
                case 91 /* InstanceOfKeyword */:
                case 90 /* InKeyword */:
                case 116 /* AsKeyword */:
                    return 7;
                case 43 /* LessThanLessThanToken */:
                case 44 /* GreaterThanGreaterThanToken */:
                case 45 /* GreaterThanGreaterThanGreaterThanToken */:
                    return 8;
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                    return 9;
                case 37 /* AsteriskToken */:
                case 39 /* SlashToken */:
                case 40 /* PercentToken */:
                    return 10;
                case 38 /* 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(187 /* BinaryExpression */, left.pos);
            node.left = left;
            node.operatorToken = operatorToken;
            node.right = right;
            return finishNode(node);
        }
        function makeAsExpression(left, right) {
            var node = createNode(195 /* AsExpression */, left.pos);
            node.expression = left;
            node.type = right;
            return finishNode(node);
        }
        function parsePrefixUnaryExpression() {
            var node = createNode(185 /* PrefixUnaryExpression */);
            node.operator = token;
            nextToken();
            node.operand = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseDeleteExpression() {
            var node = createNode(181 /* DeleteExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseTypeOfExpression() {
            var node = createNode(182 /* TypeOfExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseVoidExpression() {
            var node = createNode(183 /* VoidExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function isAwaitExpression() {
            if (token === 119 /* AwaitKeyword */) {
                if (inAwaitContext()) {
                    return true;
                }
                // here we are using similar heuristics as 'isYieldExpression'
                return lookAhead(nextTokenIsIdentifierOnSameLine);
            }
            return false;
        }
        function parseAwaitExpression() {
            var node = createNode(184 /* AwaitExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        /**
         * Parse ES7 unary expression and await expression
         *
         * ES7 UnaryExpression:
         *      1) SimpleUnaryExpression[?yield]
         *      2) IncrementExpression[?yield] ** UnaryExpression[?yield]
         */
        function parseUnaryExpressionOrHigher() {
            if (isAwaitExpression()) {
                return parseAwaitExpression();
            }
            if (isIncrementExpression()) {
                var incrementExpression = parseIncrementExpression();
                return token === 38 /* AsteriskAsteriskToken */ ?
                    parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
                    incrementExpression;
            }
            var unaryOperator = token;
            var simpleUnaryExpression = parseSimpleUnaryExpression();
            if (token === 38 /* AsteriskAsteriskToken */) {
                var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
                if (simpleUnaryExpression.kind === 177 /* 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 SimpleUnaryExpression:
         *      1) IncrementExpression[?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]
         */
        function parseSimpleUnaryExpression() {
            switch (token) {
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                case 50 /* TildeToken */:
                case 49 /* ExclamationToken */:
                    return parsePrefixUnaryExpression();
                case 78 /* DeleteKeyword */:
                    return parseDeleteExpression();
                case 101 /* TypeOfKeyword */:
                    return parseTypeOfExpression();
                case 103 /* VoidKeyword */:
                    return parseVoidExpression();
                case 25 /* LessThanToken */:
                    // This is modified UnaryExpression grammar in TypeScript
                    //  UnaryExpression (modified):
                    //      < type > UnaryExpression
                    return parseTypeAssertion();
                default:
                    return parseIncrementExpression();
            }
        }
        /**
         * Check if the current token can possibly be an ES7 increment expression.
         *
         * ES7 IncrementExpression:
         *      LeftHandSideExpression[?Yield]
         *      LeftHandSideExpression[?Yield][no LineTerminator here]++
         *      LeftHandSideExpression[?Yield][no LineTerminator here]--
         *      ++LeftHandSideExpression[?Yield]
         *      --LeftHandSideExpression[?Yield]
         */
        function isIncrementExpression() {
            // This function is called inside parseUnaryExpression to decide
            // whether to call parseSimpleUnaryExpression or call parseIncrementExpression directly
            switch (token) {
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                case 50 /* TildeToken */:
                case 49 /* ExclamationToken */:
                case 78 /* DeleteKeyword */:
                case 101 /* TypeOfKeyword */:
                case 103 /* VoidKeyword */:
                    return false;
                case 25 /* 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.
                // Fall through
                default:
                    return true;
            }
        }
        /**
         * Parse ES7 IncrementExpression. IncrementExpression is used instead of ES6's PostFixExpression.
         *
         * ES7 IncrementExpression[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 parseIncrementExpression() {
            if (token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) {
                var node = createNode(185 /* PrefixUnaryExpression */);
                node.operator = token;
                nextToken();
                node.operand = parseLeftHandSideExpressionOrHigher();
                return finishNode(node);
            }
            else if (sourceFile.languageVariant === 1 /* JSX */ && token === 25 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeyword)) {
                // JSXElement is part of primaryExpression
                return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
            }
            var expression = parseLeftHandSideExpressionOrHigher();
            ts.Debug.assert(ts.isLeftHandSideExpression(expression));
            if ((token === 41 /* PlusPlusToken */ || token === 42 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
                var node = createNode(186 /* 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
            //      super   (   ArgumentListopt   )
            //      super.IdentifierName
            //
            // Because of the recursion in these calls, we need to bottom out first.  There are two
            // bottom out states we can run into.  Either we see 'super' which must start either of
            // the last two CallExpression productions.  Or we have a MemberExpression which either
            // completes the LeftHandSideExpression, or starts the beginning of the first four
            // CallExpression productions.
            var expression = token === 95 /* 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 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 === 17 /* OpenParenToken */ || token === 21 /* DotToken */ || token === 19 /* 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(172 /* PropertyAccessExpression */, expression.pos);
            node.expression = expression;
            parseExpectedToken(21 /* 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 === 69 /* Identifier */) {
                return lhs.text === rhs.text;
            }
            if (lhs.kind === 97 /* 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.text === rhs.name.text &&
                tagNamesAreEquivalent(lhs.expression, rhs.expression);
        }
        function parseJsxElementOrSelfClosingElement(inExpressionContext) {
            var opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
            var result;
            if (opening.kind === 243 /* JsxOpeningElement */) {
                var node = createNode(241 /* 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 === 242 /* 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 === 25 /* LessThanToken */) {
                var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); });
                if (invalidElement) {
                    parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
                    var badNode = createNode(187 /* BinaryExpression */, result.pos);
                    badNode.end = invalidElement.end;
                    badNode.left = result;
                    badNode.right = invalidElement;
                    badNode.operatorToken = createMissingNode(24 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
                    badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
                    return badNode;
                }
            }
            return result;
        }
        function parseJsxText() {
            var node = createNode(244 /* JsxText */, scanner.getStartPos());
            token = scanner.scanJsxToken();
            return finishNode(node);
        }
        function parseJsxChild() {
            switch (token) {
                case 244 /* JsxText */:
                    return parseJsxText();
                case 15 /* OpenBraceToken */:
                    return parseJsxExpression(/*inExpressionContext*/ false);
                case 25 /* LessThanToken */:
                    return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
            }
            ts.Debug.fail("Unknown JSX child kind " + token);
        }
        function parseJsxChildren(openingTagName) {
            var result = [];
            result.pos = scanner.getStartPos();
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << 14 /* JsxChildren */;
            while (true) {
                token = scanner.reScanJsxToken();
                if (token === 26 /* 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;
                }
                result.push(parseJsxChild());
            }
            result.end = scanner.getTokenPos();
            parsingContext = saveParsingContext;
            return result;
        }
        function parseJsxOpeningOrSelfClosingElement(inExpressionContext) {
            var fullStart = scanner.getStartPos();
            parseExpected(25 /* LessThanToken */);
            var tagName = parseJsxElementName();
            var attributes = parseList(13 /* JsxAttributes */, parseJsxAttribute);
            var node;
            if (token === 27 /* 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(243 /* JsxOpeningElement */, fullStart);
                scanJsxText();
            }
            else {
                parseExpected(39 /* SlashToken */);
                if (inExpressionContext) {
                    parseExpected(27 /* GreaterThanToken */);
                }
                else {
                    parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                    scanJsxText();
                }
                node = createNode(242 /* 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 === 97 /* ThisKeyword */ ?
                parseTokenNode() : parseIdentifierName();
            while (parseOptional(21 /* DotToken */)) {
                var propertyAccess = createNode(172 /* PropertyAccessExpression */, expression.pos);
                propertyAccess.expression = expression;
                propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
                expression = finishNode(propertyAccess);
            }
            return expression;
        }
        function parseJsxExpression(inExpressionContext) {
            var node = createNode(248 /* JsxExpression */);
            parseExpected(15 /* OpenBraceToken */);
            if (token !== 16 /* CloseBraceToken */) {
                node.expression = parseAssignmentExpressionOrHigher();
            }
            if (inExpressionContext) {
                parseExpected(16 /* CloseBraceToken */);
            }
            else {
                parseExpected(16 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseJsxAttribute() {
            if (token === 15 /* OpenBraceToken */) {
                return parseJsxSpreadAttribute();
            }
            scanJsxIdentifier();
            var node = createNode(246 /* JsxAttribute */);
            node.name = parseIdentifierName();
            if (parseOptional(56 /* EqualsToken */)) {
                switch (token) {
                    case 9 /* StringLiteral */:
                        node.initializer = parseLiteralNode();
                        break;
                    default:
                        node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
                        break;
                }
            }
            return finishNode(node);
        }
        function parseJsxSpreadAttribute() {
            var node = createNode(247 /* JsxSpreadAttribute */);
            parseExpected(15 /* OpenBraceToken */);
            parseExpected(22 /* DotDotDotToken */);
            node.expression = parseExpression();
            parseExpected(16 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseJsxClosingElement(inExpressionContext) {
            var node = createNode(245 /* JsxClosingElement */);
            parseExpected(26 /* LessThanSlashToken */);
            node.tagName = parseJsxElementName();
            if (inExpressionContext) {
                parseExpected(27 /* GreaterThanToken */);
            }
            else {
                parseExpected(27 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseTypeAssertion() {
            var node = createNode(177 /* TypeAssertionExpression */);
            parseExpected(25 /* LessThanToken */);
            node.type = parseType();
            parseExpected(27 /* GreaterThanToken */);
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseMemberExpressionRest(expression) {
            while (true) {
                var dotToken = parseOptionalToken(21 /* DotToken */);
                if (dotToken) {
                    var propertyAccess = createNode(172 /* PropertyAccessExpression */, expression.pos);
                    propertyAccess.expression = expression;
                    propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
                    expression = finishNode(propertyAccess);
                    continue;
                }
                if (token === 49 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                    nextToken();
                    var nonNullExpression = createNode(196 /* 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(19 /* OpenBracketToken */)) {
                    var indexedAccess = createNode(173 /* 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 !== 20 /* 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(20 /* CloseBracketToken */);
                    expression = finishNode(indexedAccess);
                    continue;
                }
                if (token === 11 /* NoSubstitutionTemplateLiteral */ || token === 12 /* TemplateHead */) {
                    var tagExpression = createNode(176 /* TaggedTemplateExpression */, expression.pos);
                    tagExpression.tag = expression;
                    tagExpression.template = token === 11 /* NoSubstitutionTemplateLiteral */
                        ? parseLiteralNode()
                        : parseTemplateExpression();
                    expression = finishNode(tagExpression);
                    continue;
                }
                return expression;
            }
        }
        function parseCallExpressionRest(expression) {
            while (true) {
                expression = parseMemberExpressionRest(expression);
                if (token === 25 /* 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(174 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.typeArguments = typeArguments;
                    callExpr.arguments = parseArgumentList();
                    expression = finishNode(callExpr);
                    continue;
                }
                else if (token === 17 /* OpenParenToken */) {
                    var callExpr = createNode(174 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.arguments = parseArgumentList();
                    expression = finishNode(callExpr);
                    continue;
                }
                return expression;
            }
        }
        function parseArgumentList() {
            parseExpected(17 /* OpenParenToken */);
            var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
            parseExpected(18 /* CloseParenToken */);
            return result;
        }
        function parseTypeArgumentsInExpression() {
            if (!parseOptional(25 /* LessThanToken */)) {
                return undefined;
            }
            var typeArguments = parseDelimitedList(18 /* TypeArguments */, parseType);
            if (!parseExpected(27 /* 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 17 /* 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 21 /* DotToken */: // foo<x>.
                case 18 /* CloseParenToken */: // foo<x>)
                case 20 /* CloseBracketToken */: // foo<x>]
                case 54 /* ColonToken */: // foo<x>:
                case 23 /* SemicolonToken */: // foo<x>;
                case 53 /* QuestionToken */: // foo<x>?
                case 30 /* EqualsEqualsToken */: // foo<x> ==
                case 32 /* EqualsEqualsEqualsToken */: // foo<x> ===
                case 31 /* ExclamationEqualsToken */: // foo<x> !=
                case 33 /* ExclamationEqualsEqualsToken */: // foo<x> !==
                case 51 /* AmpersandAmpersandToken */: // foo<x> &&
                case 52 /* BarBarToken */: // foo<x> ||
                case 48 /* CaretToken */: // foo<x> ^
                case 46 /* AmpersandToken */: // foo<x> &
                case 47 /* BarToken */: // foo<x> |
                case 16 /* CloseBraceToken */: // foo<x> }
                case 1 /* EndOfFileToken */:
                    // 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 24 /* CommaToken */: // foo<x>,
                case 15 /* 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 11 /* NoSubstitutionTemplateLiteral */:
                    return parseLiteralNode();
                case 97 /* ThisKeyword */:
                case 95 /* SuperKeyword */:
                case 93 /* NullKeyword */:
                case 99 /* TrueKeyword */:
                case 84 /* FalseKeyword */:
                    return parseTokenNode();
                case 17 /* OpenParenToken */:
                    return parseParenthesizedExpression();
                case 19 /* OpenBracketToken */:
                    return parseArrayLiteralExpression();
                case 15 /* OpenBraceToken */:
                    return parseObjectLiteralExpression();
                case 118 /* 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 73 /* ClassKeyword */:
                    return parseClassExpression();
                case 87 /* FunctionKeyword */:
                    return parseFunctionExpression();
                case 92 /* NewKeyword */:
                    return parseNewExpression();
                case 39 /* SlashToken */:
                case 61 /* SlashEqualsToken */:
                    if (reScanSlashToken() === 10 /* RegularExpressionLiteral */) {
                        return parseLiteralNode();
                    }
                    break;
                case 12 /* TemplateHead */:
                    return parseTemplateExpression();
            }
            return parseIdentifier(ts.Diagnostics.Expression_expected);
        }
        function parseParenthesizedExpression() {
            var node = createNode(178 /* ParenthesizedExpression */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(18 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseSpreadElement() {
            var node = createNode(191 /* SpreadElementExpression */);
            parseExpected(22 /* DotDotDotToken */);
            node.expression = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseArgumentOrArrayLiteralElement() {
            return token === 22 /* DotDotDotToken */ ? parseSpreadElement() :
                token === 24 /* CommaToken */ ? createNode(193 /* OmittedExpression */) :
                    parseAssignmentExpressionOrHigher();
        }
        function parseArgumentExpression() {
            return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
        }
        function parseArrayLiteralExpression() {
            var node = createNode(170 /* ArrayLiteralExpression */);
            parseExpected(19 /* OpenBracketToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
            parseExpected(20 /* CloseBracketToken */);
            return finishNode(node);
        }
        function tryParseAccessorDeclaration(fullStart, decorators, modifiers) {
            if (parseContextualModifier(123 /* GetKeyword */)) {
                return addJSDocComment(parseAccessorDeclaration(149 /* GetAccessor */, fullStart, decorators, modifiers));
            }
            else if (parseContextualModifier(131 /* SetKeyword */)) {
                return parseAccessorDeclaration(150 /* SetAccessor */, fullStart, decorators, modifiers);
            }
            return undefined;
        }
        function parseObjectLiteralElement() {
            var fullStart = scanner.getStartPos();
            var decorators = parseDecorators();
            var modifiers = parseModifiers();
            var accessor = tryParseAccessorDeclaration(fullStart, decorators, modifiers);
            if (accessor) {
                return accessor;
            }
            var asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            // Disallowing of optional property assignments happens in the grammar checker.
            var questionToken = parseOptionalToken(53 /* QuestionToken */);
            if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* 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 === 24 /* CommaToken */ || token === 16 /* CloseBraceToken */ || token === 56 /* EqualsToken */);
            if (isShorthandPropertyAssignment) {
                var shorthandDeclaration = createNode(254 /* ShorthandPropertyAssignment */, fullStart);
                shorthandDeclaration.name = propertyName;
                shorthandDeclaration.questionToken = questionToken;
                var equalsToken = parseOptionalToken(56 /* EqualsToken */);
                if (equalsToken) {
                    shorthandDeclaration.equalsToken = equalsToken;
                    shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
                }
                return addJSDocComment(finishNode(shorthandDeclaration));
            }
            else {
                var propertyAssignment = createNode(253 /* PropertyAssignment */, fullStart);
                propertyAssignment.modifiers = modifiers;
                propertyAssignment.name = propertyName;
                propertyAssignment.questionToken = questionToken;
                parseExpected(54 /* ColonToken */);
                propertyAssignment.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
                return addJSDocComment(finishNode(propertyAssignment));
            }
        }
        function parseObjectLiteralExpression() {
            var node = createNode(171 /* ObjectLiteralExpression */);
            parseExpected(15 /* OpenBraceToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
            parseExpected(16 /* 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(179 /* FunctionExpression */);
            setModifiers(node, parseModifiers());
            parseExpected(87 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
            var isGenerator = !!node.asteriskToken;
            var isAsync = !!(node.flags & 256 /* Async */);
            node.name =
                isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
                    isGenerator ? doInYieldContext(parseOptionalIdentifier) :
                        isAsync ? doInAwaitContext(parseOptionalIdentifier) :
                            parseOptionalIdentifier();
            fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
            node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return addJSDocComment(finishNode(node));
        }
        function parseOptionalIdentifier() {
            return isIdentifier() ? parseIdentifier() : undefined;
        }
        function parseNewExpression() {
            var node = createNode(175 /* NewExpression */);
            parseExpected(92 /* NewKeyword */);
            node.expression = parseMemberExpressionOrHigher();
            node.typeArguments = tryParse(parseTypeArgumentsInExpression);
            if (node.typeArguments || token === 17 /* OpenParenToken */) {
                node.arguments = parseArgumentList();
            }
            return finishNode(node);
        }
        // STATEMENTS
        function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
            var node = createNode(199 /* Block */);
            if (parseExpected(15 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(16 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseFunctionBlock(allowYield, allowAwait, ignoreMissingOpenBrace, diagnosticMessage) {
            var savedYieldContext = inYieldContext();
            setYieldContext(allowYield);
            var savedAwaitContext = inAwaitContext();
            setAwaitContext(allowAwait);
            // 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(ignoreMissingOpenBrace, diagnosticMessage);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return block;
        }
        function parseEmptyStatement() {
            var node = createNode(201 /* EmptyStatement */);
            parseExpected(23 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseIfStatement() {
            var node = createNode(203 /* IfStatement */);
            parseExpected(88 /* IfKeyword */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(18 /* CloseParenToken */);
            node.thenStatement = parseStatement();
            node.elseStatement = parseOptional(80 /* ElseKeyword */) ? parseStatement() : undefined;
            return finishNode(node);
        }
        function parseDoStatement() {
            var node = createNode(204 /* DoStatement */);
            parseExpected(79 /* DoKeyword */);
            node.statement = parseStatement();
            parseExpected(104 /* WhileKeyword */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(18 /* 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(23 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseWhileStatement() {
            var node = createNode(205 /* WhileStatement */);
            parseExpected(104 /* WhileKeyword */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(18 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseForOrForInOrForOfStatement() {
            var pos = getNodePos();
            parseExpected(86 /* ForKeyword */);
            parseExpected(17 /* OpenParenToken */);
            var initializer = undefined;
            if (token !== 23 /* SemicolonToken */) {
                if (token === 102 /* VarKeyword */ || token === 108 /* LetKeyword */ || token === 74 /* ConstKeyword */) {
                    initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
                }
                else {
                    initializer = disallowInAnd(parseExpression);
                }
            }
            var forOrForInOrForOfStatement;
            if (parseOptional(90 /* InKeyword */)) {
                var forInStatement = createNode(207 /* ForInStatement */, pos);
                forInStatement.initializer = initializer;
                forInStatement.expression = allowInAnd(parseExpression);
                parseExpected(18 /* CloseParenToken */);
                forOrForInOrForOfStatement = forInStatement;
            }
            else if (parseOptional(138 /* OfKeyword */)) {
                var forOfStatement = createNode(208 /* ForOfStatement */, pos);
                forOfStatement.initializer = initializer;
                forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
                parseExpected(18 /* CloseParenToken */);
                forOrForInOrForOfStatement = forOfStatement;
            }
            else {
                var forStatement = createNode(206 /* ForStatement */, pos);
                forStatement.initializer = initializer;
                parseExpected(23 /* SemicolonToken */);
                if (token !== 23 /* SemicolonToken */ && token !== 18 /* CloseParenToken */) {
                    forStatement.condition = allowInAnd(parseExpression);
                }
                parseExpected(23 /* SemicolonToken */);
                if (token !== 18 /* CloseParenToken */) {
                    forStatement.incrementor = allowInAnd(parseExpression);
                }
                parseExpected(18 /* CloseParenToken */);
                forOrForInOrForOfStatement = forStatement;
            }
            forOrForInOrForOfStatement.statement = parseStatement();
            return finishNode(forOrForInOrForOfStatement);
        }
        function parseBreakOrContinueStatement(kind) {
            var node = createNode(kind);
            parseExpected(kind === 210 /* BreakStatement */ ? 70 /* BreakKeyword */ : 75 /* ContinueKeyword */);
            if (!canParseSemicolon()) {
                node.label = parseIdentifier();
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseReturnStatement() {
            var node = createNode(211 /* ReturnStatement */);
            parseExpected(94 /* ReturnKeyword */);
            if (!canParseSemicolon()) {
                node.expression = allowInAnd(parseExpression);
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseWithStatement() {
            var node = createNode(212 /* WithStatement */);
            parseExpected(105 /* WithKeyword */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(18 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseCaseClause() {
            var node = createNode(249 /* CaseClause */);
            parseExpected(71 /* CaseKeyword */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(54 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseDefaultClause() {
            var node = createNode(250 /* DefaultClause */);
            parseExpected(77 /* DefaultKeyword */);
            parseExpected(54 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseCaseOrDefaultClause() {
            return token === 71 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
        }
        function parseSwitchStatement() {
            var node = createNode(213 /* SwitchStatement */);
            parseExpected(96 /* SwitchKeyword */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(18 /* CloseParenToken */);
            var caseBlock = createNode(227 /* CaseBlock */, scanner.getStartPos());
            parseExpected(15 /* OpenBraceToken */);
            caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
            parseExpected(16 /* 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(215 /* ThrowStatement */);
            parseExpected(98 /* ThrowKeyword */);
            node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
            parseSemicolon();
            return finishNode(node);
        }
        // TODO: Review for error recovery
        function parseTryStatement() {
            var node = createNode(216 /* TryStatement */);
            parseExpected(100 /* TryKeyword */);
            node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            node.catchClause = token === 72 /* 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 === 85 /* FinallyKeyword */) {
                parseExpected(85 /* FinallyKeyword */);
                node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            }
            return finishNode(node);
        }
        function parseCatchClause() {
            var result = createNode(252 /* CatchClause */);
            parseExpected(72 /* CatchKeyword */);
            if (parseExpected(17 /* OpenParenToken */)) {
                result.variableDeclaration = parseVariableDeclaration();
            }
            parseExpected(18 /* CloseParenToken */);
            result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
            return finishNode(result);
        }
        function parseDebuggerStatement() {
            var node = createNode(217 /* DebuggerStatement */);
            parseExpected(76 /* 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 === 69 /* Identifier */ && parseOptional(54 /* ColonToken */)) {
                var labeledStatement = createNode(214 /* LabeledStatement */, fullStart);
                labeledStatement.label = expression;
                labeledStatement.statement = parseStatement();
                return addJSDocComment(finishNode(labeledStatement));
            }
            else {
                var expressionStatement = createNode(202 /* ExpressionStatement */, fullStart);
                expressionStatement.expression = expression;
                parseSemicolon();
                return addJSDocComment(finishNode(expressionStatement));
            }
        }
        function nextTokenIsIdentifierOrKeywordOnSameLine() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token) && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsFunctionKeywordOnSameLine() {
            nextToken();
            return token === 87 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
            nextToken();
            return (ts.tokenIsIdentifierOrKeyword(token) || token === 8 /* NumericLiteral */) && !scanner.hasPrecedingLineBreak();
        }
        function isDeclaration() {
            while (true) {
                switch (token) {
                    case 102 /* VarKeyword */:
                    case 108 /* LetKeyword */:
                    case 74 /* ConstKeyword */:
                    case 87 /* FunctionKeyword */:
                    case 73 /* ClassKeyword */:
                    case 81 /* 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 107 /* InterfaceKeyword */:
                    case 134 /* TypeKeyword */:
                        return nextTokenIsIdentifierOnSameLine();
                    case 125 /* ModuleKeyword */:
                    case 126 /* NamespaceKeyword */:
                        return nextTokenIsIdentifierOrStringLiteralOnSameLine();
                    case 115 /* AbstractKeyword */:
                    case 118 /* AsyncKeyword */:
                    case 122 /* DeclareKeyword */:
                    case 110 /* PrivateKeyword */:
                    case 111 /* ProtectedKeyword */:
                    case 112 /* PublicKeyword */:
                    case 128 /* ReadonlyKeyword */:
                        nextToken();
                        // ASI takes effect for this modifier.
                        if (scanner.hasPrecedingLineBreak()) {
                            return false;
                        }
                        continue;
                    case 137 /* GlobalKeyword */:
                        nextToken();
                        return token === 15 /* OpenBraceToken */ || token === 69 /* Identifier */ || token === 82 /* ExportKeyword */;
                    case 89 /* ImportKeyword */:
                        nextToken();
                        return token === 9 /* StringLiteral */ || token === 37 /* AsteriskToken */ ||
                            token === 15 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token);
                    case 82 /* ExportKeyword */:
                        nextToken();
                        if (token === 56 /* EqualsToken */ || token === 37 /* AsteriskToken */ ||
                            token === 15 /* OpenBraceToken */ || token === 77 /* DefaultKeyword */ ||
                            token === 116 /* AsKeyword */) {
                            return true;
                        }
                        continue;
                    case 113 /* StaticKeyword */:
                        nextToken();
                        continue;
                    default:
                        return false;
                }
            }
        }
        function isStartOfDeclaration() {
            return lookAhead(isDeclaration);
        }
        function isStartOfStatement() {
            switch (token) {
                case 55 /* AtToken */:
                case 23 /* SemicolonToken */:
                case 15 /* OpenBraceToken */:
                case 102 /* VarKeyword */:
                case 108 /* LetKeyword */:
                case 87 /* FunctionKeyword */:
                case 73 /* ClassKeyword */:
                case 81 /* EnumKeyword */:
                case 88 /* IfKeyword */:
                case 79 /* DoKeyword */:
                case 104 /* WhileKeyword */:
                case 86 /* ForKeyword */:
                case 75 /* ContinueKeyword */:
                case 70 /* BreakKeyword */:
                case 94 /* ReturnKeyword */:
                case 105 /* WithKeyword */:
                case 96 /* SwitchKeyword */:
                case 98 /* ThrowKeyword */:
                case 100 /* TryKeyword */:
                case 76 /* 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 72 /* CatchKeyword */:
                case 85 /* FinallyKeyword */:
                    return true;
                case 74 /* ConstKeyword */:
                case 82 /* ExportKeyword */:
                case 89 /* ImportKeyword */:
                    return isStartOfDeclaration();
                case 118 /* AsyncKeyword */:
                case 122 /* DeclareKeyword */:
                case 107 /* InterfaceKeyword */:
                case 125 /* ModuleKeyword */:
                case 126 /* NamespaceKeyword */:
                case 134 /* TypeKeyword */:
                case 137 /* GlobalKeyword */:
                    // When these don't start a declaration, they're an identifier in an expression statement
                    return true;
                case 112 /* PublicKeyword */:
                case 110 /* PrivateKeyword */:
                case 111 /* ProtectedKeyword */:
                case 113 /* StaticKeyword */:
                case 128 /* 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 === 15 /* OpenBraceToken */ || token === 19 /* 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 23 /* SemicolonToken */:
                    return parseEmptyStatement();
                case 15 /* OpenBraceToken */:
                    return parseBlock(/*ignoreMissingOpenBrace*/ false);
                case 102 /* VarKeyword */:
                    return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                case 108 /* LetKeyword */:
                    if (isLetDeclaration()) {
                        return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                    }
                    break;
                case 87 /* FunctionKeyword */:
                    return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                case 73 /* ClassKeyword */:
                    return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
                case 88 /* IfKeyword */:
                    return parseIfStatement();
                case 79 /* DoKeyword */:
                    return parseDoStatement();
                case 104 /* WhileKeyword */:
                    return parseWhileStatement();
                case 86 /* ForKeyword */:
                    return parseForOrForInOrForOfStatement();
                case 75 /* ContinueKeyword */:
                    return parseBreakOrContinueStatement(209 /* ContinueStatement */);
                case 70 /* BreakKeyword */:
                    return parseBreakOrContinueStatement(210 /* BreakStatement */);
                case 94 /* ReturnKeyword */:
                    return parseReturnStatement();
                case 105 /* WithKeyword */:
                    return parseWithStatement();
                case 96 /* SwitchKeyword */:
                    return parseSwitchStatement();
                case 98 /* ThrowKeyword */:
                    return parseThrowStatement();
                case 100 /* TryKeyword */:
                // Include 'catch' and 'finally' for error recovery.
                case 72 /* CatchKeyword */:
                case 85 /* FinallyKeyword */:
                    return parseTryStatement();
                case 76 /* DebuggerKeyword */:
                    return parseDebuggerStatement();
                case 55 /* AtToken */:
                    return parseDeclaration();
                case 118 /* AsyncKeyword */:
                case 107 /* InterfaceKeyword */:
                case 134 /* TypeKeyword */:
                case 125 /* ModuleKeyword */:
                case 126 /* NamespaceKeyword */:
                case 122 /* DeclareKeyword */:
                case 74 /* ConstKeyword */:
                case 81 /* EnumKeyword */:
                case 82 /* ExportKeyword */:
                case 89 /* ImportKeyword */:
                case 110 /* PrivateKeyword */:
                case 111 /* ProtectedKeyword */:
                case 112 /* PublicKeyword */:
                case 115 /* AbstractKeyword */:
                case 113 /* StaticKeyword */:
                case 128 /* ReadonlyKeyword */:
                case 137 /* GlobalKeyword */:
                    if (isStartOfDeclaration()) {
                        return parseDeclaration();
                    }
                    break;
            }
            return parseExpressionOrLabeledStatement();
        }
        function parseDeclaration() {
            var fullStart = getNodePos();
            var decorators = parseDecorators();
            var modifiers = parseModifiers();
            switch (token) {
                case 102 /* VarKeyword */:
                case 108 /* LetKeyword */:
                case 74 /* ConstKeyword */:
                    return parseVariableStatement(fullStart, decorators, modifiers);
                case 87 /* FunctionKeyword */:
                    return parseFunctionDeclaration(fullStart, decorators, modifiers);
                case 73 /* ClassKeyword */:
                    return parseClassDeclaration(fullStart, decorators, modifiers);
                case 107 /* InterfaceKeyword */:
                    return parseInterfaceDeclaration(fullStart, decorators, modifiers);
                case 134 /* TypeKeyword */:
                    return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
                case 81 /* EnumKeyword */:
                    return parseEnumDeclaration(fullStart, decorators, modifiers);
                case 137 /* GlobalKeyword */:
                case 125 /* ModuleKeyword */:
                case 126 /* NamespaceKeyword */:
                    return parseModuleDeclaration(fullStart, decorators, modifiers);
                case 89 /* ImportKeyword */:
                    return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers);
                case 82 /* ExportKeyword */:
                    nextToken();
                    switch (token) {
                        case 77 /* DefaultKeyword */:
                        case 56 /* EqualsToken */:
                            return parseExportAssignment(fullStart, decorators, modifiers);
                        case 116 /* 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(239 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                        node.pos = fullStart;
                        node.decorators = decorators;
                        setModifiers(node, modifiers);
                        return finishNode(node);
                    }
            }
        }
        function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === 9 /* StringLiteral */);
        }
        function parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage) {
            if (token !== 15 /* OpenBraceToken */ && canParseSemicolon()) {
                parseSemicolon();
                return;
            }
            return parseFunctionBlock(isGenerator, isAsync, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
        }
        // DECLARATIONS
        function parseArrayBindingElement() {
            if (token === 24 /* CommaToken */) {
                return createNode(193 /* OmittedExpression */);
            }
            var node = createNode(169 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(22 /* DotDotDotToken */);
            node.name = parseIdentifierOrPattern();
            node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
            return finishNode(node);
        }
        function parseObjectBindingElement() {
            var node = createNode(169 /* BindingElement */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            if (tokenIsIdentifier && token !== 54 /* ColonToken */) {
                node.name = propertyName;
            }
            else {
                parseExpected(54 /* ColonToken */);
                node.propertyName = propertyName;
                node.name = parseIdentifierOrPattern();
            }
            node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
            return finishNode(node);
        }
        function parseObjectBindingPattern() {
            var node = createNode(167 /* ObjectBindingPattern */);
            parseExpected(15 /* OpenBraceToken */);
            node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
            parseExpected(16 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseArrayBindingPattern() {
            var node = createNode(168 /* ArrayBindingPattern */);
            parseExpected(19 /* OpenBracketToken */);
            node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
            parseExpected(20 /* CloseBracketToken */);
            return finishNode(node);
        }
        function isIdentifierOrPattern() {
            return token === 15 /* OpenBraceToken */ || token === 19 /* OpenBracketToken */ || isIdentifier();
        }
        function parseIdentifierOrPattern() {
            if (token === 19 /* OpenBracketToken */) {
                return parseArrayBindingPattern();
            }
            if (token === 15 /* OpenBraceToken */) {
                return parseObjectBindingPattern();
            }
            return parseIdentifier();
        }
        function parseVariableDeclaration() {
            var node = createNode(218 /* VariableDeclaration */);
            node.name = parseIdentifierOrPattern();
            node.type = parseTypeAnnotation();
            if (!isInOrOfKeyword(token)) {
                node.initializer = parseInitializer(/*inParameter*/ false);
            }
            return finishNode(node);
        }
        function parseVariableDeclarationList(inForStatementInitializer) {
            var node = createNode(219 /* VariableDeclarationList */);
            switch (token) {
                case 102 /* VarKeyword */:
                    break;
                case 108 /* LetKeyword */:
                    node.flags |= 1024 /* Let */;
                    break;
                case 74 /* ConstKeyword */:
                    node.flags |= 2048 /* 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 === 138 /* 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() === 18 /* CloseParenToken */;
        }
        function parseVariableStatement(fullStart, decorators, modifiers) {
            var node = createNode(200 /* VariableStatement */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
            parseSemicolon();
            return addJSDocComment(finishNode(node));
        }
        function parseFunctionDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(220 /* FunctionDeclaration */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            parseExpected(87 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(37 /* AsteriskToken */);
            node.name = node.flags & 512 /* Default */ ? parseOptionalIdentifier() : parseIdentifier();
            var isGenerator = !!node.asteriskToken;
            var isAsync = !!(node.flags & 256 /* Async */);
            fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, ts.Diagnostics.or_expected);
            return addJSDocComment(finishNode(node));
        }
        function parseConstructorDeclaration(pos, decorators, modifiers) {
            var node = createNode(148 /* Constructor */, pos);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            parseExpected(121 /* ConstructorKeyword */);
            fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
            node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, ts.Diagnostics.or_expected);
            return addJSDocComment(finishNode(node));
        }
        function parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, name, questionToken, diagnosticMessage) {
            var method = createNode(147 /* MethodDeclaration */, fullStart);
            method.decorators = decorators;
            setModifiers(method, modifiers);
            method.asteriskToken = asteriskToken;
            method.name = name;
            method.questionToken = questionToken;
            var isGenerator = !!asteriskToken;
            var isAsync = !!(method.flags & 256 /* Async */);
            fillSignature(54 /* ColonToken */, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
            method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
            return addJSDocComment(finishNode(method));
        }
        function parsePropertyDeclaration(fullStart, decorators, modifiers, name, questionToken) {
            var property = createNode(145 /* PropertyDeclaration */, fullStart);
            property.decorators = decorators;
            setModifiers(property, 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 = modifiers && modifiers.flags & 32 /* Static */
                ? allowInAnd(parseNonParameterInitializer)
                : doOutsideOfContext(8388608 /* YieldContext */ | 4194304 /* DisallowInContext */, parseNonParameterInitializer);
            parseSemicolon();
            return finishNode(property);
        }
        function parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers) {
            var asteriskToken = parseOptionalToken(37 /* 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(53 /* QuestionToken */);
            if (asteriskToken || token === 17 /* OpenParenToken */ || token === 25 /* 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;
            setModifiers(node, modifiers);
            node.name = parsePropertyName();
            fillSignature(54 /* ColonToken */, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
            node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
            return finishNode(node);
        }
        function isClassMemberModifier(idToken) {
            switch (idToken) {
                case 112 /* PublicKeyword */:
                case 110 /* PrivateKeyword */:
                case 111 /* ProtectedKeyword */:
                case 113 /* StaticKeyword */:
                case 128 /* ReadonlyKeyword */:
                    return true;
                default:
                    return false;
            }
        }
        function isClassMemberStart() {
            var idToken;
            if (token === 55 /* 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 === 37 /* 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 === 19 /* 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 === 131 /* SetKeyword */ || idToken === 123 /* 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 17 /* OpenParenToken */: // Method declaration
                    case 25 /* LessThanToken */: // Generic Method declaration
                    case 54 /* ColonToken */: // Type Annotation for declaration
                    case 56 /* EqualsToken */: // Initializer for declaration
                    case 53 /* QuestionToken */:
                        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 decorators;
            while (true) {
                var decoratorStart = getNodePos();
                if (!parseOptional(55 /* AtToken */)) {
                    break;
                }
                if (!decorators) {
                    decorators = [];
                    decorators.pos = decoratorStart;
                }
                var decorator = createNode(143 /* Decorator */, decoratorStart);
                decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
                decorators.push(finishNode(decorator));
            }
            if (decorators) {
                decorators.end = getNodeEnd();
            }
            return decorators;
        }
        /*
         * 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 flags = 0;
            var modifiers;
            while (true) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token;
                if (token === 74 /* 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;
                    }
                }
                if (!modifiers) {
                    modifiers = [];
                    modifiers.pos = modifierStart;
                }
                flags |= ts.modifierToFlag(modifierKind);
                modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
            }
            if (modifiers) {
                modifiers.flags = flags;
                modifiers.end = scanner.getStartPos();
            }
            return modifiers;
        }
        function parseModifiersForArrowFunction() {
            var flags = 0;
            var modifiers;
            if (token === 118 /* AsyncKeyword */) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token;
                nextToken();
                modifiers = [];
                modifiers.pos = modifierStart;
                flags |= ts.modifierToFlag(modifierKind);
                modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
                modifiers.flags = flags;
                modifiers.end = scanner.getStartPos();
            }
            return modifiers;
        }
        function parseClassElement() {
            if (token === 23 /* SemicolonToken */) {
                var result = createNode(198 /* 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 === 121 /* 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 === 37 /* AsteriskToken */ ||
                token === 19 /* OpenBracketToken */) {
                return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
            }
            if (decorators || modifiers) {
                // treat this as a property declaration with a missing name.
                var name_7 = createMissingNode(69 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                return parsePropertyDeclaration(fullStart, decorators, modifiers, name_7, /*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, 192 /* ClassExpression */);
        }
        function parseClassDeclaration(fullStart, decorators, modifiers) {
            return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 221 /* ClassDeclaration */);
        }
        function parseClassDeclarationOrExpression(fullStart, decorators, modifiers, kind) {
            var node = createNode(kind, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            parseExpected(73 /* ClassKeyword */);
            node.name = parseNameOfClassDeclarationOrExpression();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
            if (parseExpected(15 /* OpenBraceToken */)) {
                // ClassTail[Yield,Await] : (Modified) See 14.5
                //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
                node.members = parseClassMembers();
                parseExpected(16 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return 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 === 106 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
        }
        function parseHeritageClauses(isClassHeritageClause) {
            // ClassTail[Yield,Await] : (Modified) See 14.5
            //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
            if (isHeritageClause()) {
                return parseList(20 /* HeritageClauses */, parseHeritageClause);
            }
            return undefined;
        }
        function parseHeritageClause() {
            if (token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */) {
                var node = createNode(251 /* HeritageClause */);
                node.token = token;
                nextToken();
                node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
                return finishNode(node);
            }
            return undefined;
        }
        function parseExpressionWithTypeArguments() {
            var node = createNode(194 /* ExpressionWithTypeArguments */);
            node.expression = parseLeftHandSideExpressionOrHigher();
            if (token === 25 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(18 /* TypeArguments */, parseType, 25 /* LessThanToken */, 27 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        function isHeritageClause() {
            return token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
        }
        function parseClassMembers() {
            return parseList(5 /* ClassMembers */, parseClassElement);
        }
        function parseInterfaceDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(222 /* InterfaceDeclaration */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            parseExpected(107 /* InterfaceKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseTypeAliasDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(223 /* TypeAliasDeclaration */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            parseExpected(134 /* TypeKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            parseExpected(56 /* EqualsToken */);
            node.type = parseType();
            parseSemicolon();
            return 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(255 /* EnumMember */, scanner.getStartPos());
            node.name = parsePropertyName();
            node.initializer = allowInAnd(parseNonParameterInitializer);
            return finishNode(node);
        }
        function parseEnumDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(224 /* EnumDeclaration */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            parseExpected(81 /* EnumKeyword */);
            node.name = parseIdentifier();
            if (parseExpected(15 /* OpenBraceToken */)) {
                node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember);
                parseExpected(16 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleBlock() {
            var node = createNode(226 /* ModuleBlock */, scanner.getStartPos());
            if (parseExpected(15 /* OpenBraceToken */)) {
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(16 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags) {
            var node = createNode(225 /* 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 & 4096 /* Namespace */;
            node.decorators = decorators;
            setModifiers(node, modifiers);
            node.flags |= flags;
            node.name = parseIdentifier();
            node.body = parseOptional(21 /* DotToken */)
                ? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, 1 /* Export */ | namespaceFlag)
                : parseModuleBlock();
            return finishNode(node);
        }
        function parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers) {
            var node = createNode(225 /* ModuleDeclaration */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            if (token === 137 /* GlobalKeyword */) {
                // parse 'global' as name of global scope augmentation
                node.name = parseIdentifier();
                node.flags |= 131072 /* GlobalAugmentation */;
            }
            else {
                node.name = parseLiteralNode(/*internName*/ true);
            }
            if (token === 15 /* OpenBraceToken */) {
                node.body = parseModuleBlock();
            }
            else {
                parseSemicolon();
            }
            return finishNode(node);
        }
        function parseModuleDeclaration(fullStart, decorators, modifiers) {
            var flags = modifiers ? modifiers.flags : 0;
            if (token === 137 /* GlobalKeyword */) {
                // global augmentation
                return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
            }
            else if (parseOptional(126 /* NamespaceKeyword */)) {
                flags |= 4096 /* Namespace */;
            }
            else {
                parseExpected(125 /* ModuleKeyword */);
                if (token === 9 /* StringLiteral */) {
                    return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
                }
            }
            return parseModuleOrNamespaceDeclaration(fullStart, decorators, modifiers, flags);
        }
        function isExternalModuleReference() {
            return token === 129 /* RequireKeyword */ &&
                lookAhead(nextTokenIsOpenParen);
        }
        function nextTokenIsOpenParen() {
            return nextToken() === 17 /* OpenParenToken */;
        }
        function nextTokenIsSlash() {
            return nextToken() === 39 /* SlashToken */;
        }
        function parseNamespaceExportDeclaration(fullStart, decorators, modifiers) {
            var exportDeclaration = createNode(228 /* NamespaceExportDeclaration */, fullStart);
            exportDeclaration.decorators = decorators;
            exportDeclaration.modifiers = modifiers;
            parseExpected(116 /* AsKeyword */);
            parseExpected(126 /* NamespaceKeyword */);
            exportDeclaration.name = parseIdentifier();
            parseExpected(23 /* SemicolonToken */);
            return finishNode(exportDeclaration);
        }
        function parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers) {
            parseExpected(89 /* ImportKeyword */);
            var afterImportPos = scanner.getStartPos();
            var identifier;
            if (isIdentifier()) {
                identifier = parseIdentifier();
                if (token !== 24 /* CommaToken */ && token !== 136 /* FromKeyword */) {
                    // ImportEquals declaration of type:
                    // import x = require("mod"); or
                    // import x = M.x;
                    var importEqualsDeclaration = createNode(229 /* ImportEqualsDeclaration */, fullStart);
                    importEqualsDeclaration.decorators = decorators;
                    setModifiers(importEqualsDeclaration, modifiers);
                    importEqualsDeclaration.name = identifier;
                    parseExpected(56 /* EqualsToken */);
                    importEqualsDeclaration.moduleReference = parseModuleReference();
                    parseSemicolon();
                    return finishNode(importEqualsDeclaration);
                }
            }
            // Import statement
            var importDeclaration = createNode(230 /* ImportDeclaration */, fullStart);
            importDeclaration.decorators = decorators;
            setModifiers(importDeclaration, modifiers);
            // ImportDeclaration:
            //  import ImportClause from ModuleSpecifier ;
            //  import ModuleSpecifier;
            if (identifier ||
                token === 37 /* AsteriskToken */ ||
                token === 15 /* OpenBraceToken */) {
                importDeclaration.importClause = parseImportClause(identifier, afterImportPos);
                parseExpected(136 /* FromKeyword */);
            }
            importDeclaration.moduleSpecifier = parseModuleSpecifier();
            parseSemicolon();
            return finishNode(importDeclaration);
        }
        function parseImportClause(identifier, fullStart) {
            // ImportClause:
            //  ImportedDefaultBinding
            //  NameSpaceImport
            //  NamedImports
            //  ImportedDefaultBinding, NameSpaceImport
            //  ImportedDefaultBinding, NamedImports
            var importClause = createNode(231 /* 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(24 /* CommaToken */)) {
                importClause.namedBindings = token === 37 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(233 /* NamedImports */);
            }
            return finishNode(importClause);
        }
        function parseModuleReference() {
            return isExternalModuleReference()
                ? parseExternalModuleReference()
                : parseEntityName(/*allowReservedWords*/ false);
        }
        function parseExternalModuleReference() {
            var node = createNode(240 /* ExternalModuleReference */);
            parseExpected(129 /* RequireKeyword */);
            parseExpected(17 /* OpenParenToken */);
            node.expression = parseModuleSpecifier();
            parseExpected(18 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseModuleSpecifier() {
            if (token === 9 /* StringLiteral */) {
                var result = parseLiteralNode();
                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(232 /* NamespaceImport */);
            parseExpected(37 /* AsteriskToken */);
            parseExpected(116 /* AsKeyword */);
            namespaceImport.name = parseIdentifier();
            return finishNode(namespaceImport);
        }
        function parseNamedImportsOrExports(kind) {
            var node = createNode(kind);
            // NamedImports:
            //  { }
            //  { ImportsList }
            //  { ImportsList, }
            // ImportsList:
            //  ImportSpecifier
            //  ImportsList, ImportSpecifier
            node.elements = parseBracketedList(21 /* ImportOrExportSpecifiers */, kind === 233 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 15 /* OpenBraceToken */, 16 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseExportSpecifier() {
            return parseImportOrExportSpecifier(238 /* ExportSpecifier */);
        }
        function parseImportSpecifier() {
            return parseImportOrExportSpecifier(234 /* 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 === 116 /* AsKeyword */) {
                node.propertyName = identifierName;
                parseExpected(116 /* AsKeyword */);
                checkIdentifierIsKeyword = ts.isKeyword(token) && !isIdentifier();
                checkIdentifierStart = scanner.getTokenPos();
                checkIdentifierEnd = scanner.getTextPos();
                node.name = parseIdentifierName();
            }
            else {
                node.name = identifierName;
            }
            if (kind === 234 /* 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(236 /* ExportDeclaration */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            if (parseOptional(37 /* AsteriskToken */)) {
                parseExpected(136 /* FromKeyword */);
                node.moduleSpecifier = parseModuleSpecifier();
            }
            else {
                node.exportClause = parseNamedImportsOrExports(237 /* 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 === 136 /* FromKeyword */ || (token === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
                    parseExpected(136 /* FromKeyword */);
                    node.moduleSpecifier = parseModuleSpecifier();
                }
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseExportAssignment(fullStart, decorators, modifiers) {
            var node = createNode(235 /* ExportAssignment */, fullStart);
            node.decorators = decorators;
            setModifiers(node, modifiers);
            if (parseOptional(56 /* EqualsToken */)) {
                node.isExportEquals = true;
            }
            else {
                parseExpected(77 /* 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;
            // 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 = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
                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);
                        }
                    }
                }
            }
            sourceFile.referencedFiles = referencedFiles;
            sourceFile.typeReferenceDirectives = typeReferenceDirectives;
            sourceFile.amdDependencies = amdDependencies;
            sourceFile.moduleName = amdModuleName;
        }
        function setExternalModuleIndicator(sourceFile) {
            sourceFile.externalModuleIndicator = ts.forEach(sourceFile.statements, function (node) {
                return node.flags & 1 /* Export */
                    || node.kind === 229 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 240 /* ExternalModuleReference */
                    || node.kind === 230 /* ImportDeclaration */
                    || node.kind === 235 /* ExportAssignment */
                    || node.kind === 236 /* 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["TypeParameters"] = 17] = "TypeParameters";
            ParsingContext[ParsingContext["TypeArguments"] = 18] = "TypeArguments";
            ParsingContext[ParsingContext["TupleElementTypes"] = 19] = "TupleElementTypes";
            ParsingContext[ParsingContext["HeritageClauses"] = 20] = "HeritageClauses";
            ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 21] = "ImportOrExportSpecifiers";
            ParsingContext[ParsingContext["JSDocFunctionParameters"] = 22] = "JSDocFunctionParameters";
            ParsingContext[ParsingContext["JSDocTypeArguments"] = 23] = "JSDocTypeArguments";
            ParsingContext[ParsingContext["JSDocRecordMembers"] = 24] = "JSDocRecordMembers";
            ParsingContext[ParsingContext["JSDocTupleTypes"] = 25] = "JSDocTupleTypes";
            ParsingContext[ParsingContext["Count"] = 26] = "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 isJSDocType() {
                switch (token) {
                    case 37 /* AsteriskToken */:
                    case 53 /* QuestionToken */:
                    case 17 /* OpenParenToken */:
                    case 19 /* OpenBracketToken */:
                    case 49 /* ExclamationToken */:
                    case 15 /* OpenBraceToken */:
                    case 87 /* FunctionKeyword */:
                    case 22 /* DotDotDotToken */:
                    case 92 /* NewKeyword */:
                    case 97 /* ThisKeyword */:
                        return true;
                }
                return ts.tokenIsIdentifierOrKeyword(token);
            }
            JSDocParser.isJSDocType = isJSDocType;
            function parseJSDocTypeExpressionForTests(content, start, length) {
                initializeState("file.js", content, 2 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                scanner.setText(content, start, length);
                token = scanner.scan();
                var jsDocTypeExpression = parseJSDocTypeExpression();
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
            // Parses out a JSDoc type expression.
            /* @internal */
            function parseJSDocTypeExpression() {
                var result = createNode(257 /* JSDocTypeExpression */, scanner.getTokenPos());
                parseExpected(15 /* OpenBraceToken */);
                result.type = parseJSDocTopLevelType();
                parseExpected(16 /* CloseBraceToken */);
                fixupParentReferences(result);
                return finishNode(result);
            }
            JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
            function parseJSDocTopLevelType() {
                var type = parseJSDocType();
                if (token === 47 /* BarToken */) {
                    var unionType = createNode(261 /* JSDocUnionType */, type.pos);
                    unionType.types = parseJSDocTypeList(type);
                    type = finishNode(unionType);
                }
                if (token === 56 /* EqualsToken */) {
                    var optionalType = createNode(268 /* JSDocOptionalType */, type.pos);
                    nextToken();
                    optionalType.type = type;
                    type = finishNode(optionalType);
                }
                return type;
            }
            function parseJSDocType() {
                var type = parseBasicTypeExpression();
                while (true) {
                    if (token === 19 /* OpenBracketToken */) {
                        var arrayType = createNode(260 /* JSDocArrayType */, type.pos);
                        arrayType.elementType = type;
                        nextToken();
                        parseExpected(20 /* CloseBracketToken */);
                        type = finishNode(arrayType);
                    }
                    else if (token === 53 /* QuestionToken */) {
                        var nullableType = createNode(263 /* JSDocNullableType */, type.pos);
                        nullableType.type = type;
                        nextToken();
                        type = finishNode(nullableType);
                    }
                    else if (token === 49 /* ExclamationToken */) {
                        var nonNullableType = createNode(264 /* JSDocNonNullableType */, type.pos);
                        nonNullableType.type = type;
                        nextToken();
                        type = finishNode(nonNullableType);
                    }
                    else {
                        break;
                    }
                }
                return type;
            }
            function parseBasicTypeExpression() {
                switch (token) {
                    case 37 /* AsteriskToken */:
                        return parseJSDocAllType();
                    case 53 /* QuestionToken */:
                        return parseJSDocUnknownOrNullableType();
                    case 17 /* OpenParenToken */:
                        return parseJSDocUnionType();
                    case 19 /* OpenBracketToken */:
                        return parseJSDocTupleType();
                    case 49 /* ExclamationToken */:
                        return parseJSDocNonNullableType();
                    case 15 /* OpenBraceToken */:
                        return parseJSDocRecordType();
                    case 87 /* FunctionKeyword */:
                        return parseJSDocFunctionType();
                    case 22 /* DotDotDotToken */:
                        return parseJSDocVariadicType();
                    case 92 /* NewKeyword */:
                        return parseJSDocConstructorType();
                    case 97 /* ThisKeyword */:
                        return parseJSDocThisType();
                    case 117 /* AnyKeyword */:
                    case 132 /* StringKeyword */:
                    case 130 /* NumberKeyword */:
                    case 120 /* BooleanKeyword */:
                    case 133 /* SymbolKeyword */:
                    case 103 /* VoidKeyword */:
                        return parseTokenNode();
                }
                // TODO (drosen): Parse string literal types in JSDoc as well.
                return parseJSDocTypeReference();
            }
            function parseJSDocThisType() {
                var result = createNode(272 /* JSDocThisType */);
                nextToken();
                parseExpected(54 /* ColonToken */);
                result.type = parseJSDocType();
                return finishNode(result);
            }
            function parseJSDocConstructorType() {
                var result = createNode(271 /* JSDocConstructorType */);
                nextToken();
                parseExpected(54 /* ColonToken */);
                result.type = parseJSDocType();
                return finishNode(result);
            }
            function parseJSDocVariadicType() {
                var result = createNode(270 /* JSDocVariadicType */);
                nextToken();
                result.type = parseJSDocType();
                return finishNode(result);
            }
            function parseJSDocFunctionType() {
                var result = createNode(269 /* JSDocFunctionType */);
                nextToken();
                parseExpected(17 /* OpenParenToken */);
                result.parameters = parseDelimitedList(22 /* JSDocFunctionParameters */, parseJSDocParameter);
                checkForTrailingComma(result.parameters);
                parseExpected(18 /* CloseParenToken */);
                if (token === 54 /* ColonToken */) {
                    nextToken();
                    result.type = parseJSDocType();
                }
                return finishNode(result);
            }
            function parseJSDocParameter() {
                var parameter = createNode(142 /* Parameter */);
                parameter.type = parseJSDocType();
                if (parseOptional(56 /* EqualsToken */)) {
                    parameter.questionToken = createNode(56 /* EqualsToken */);
                }
                return finishNode(parameter);
            }
            function parseJSDocTypeReference() {
                var result = createNode(267 /* JSDocTypeReference */);
                result.name = parseSimplePropertyName();
                if (token === 25 /* LessThanToken */) {
                    result.typeArguments = parseTypeArguments();
                }
                else {
                    while (parseOptional(21 /* DotToken */)) {
                        if (token === 25 /* LessThanToken */) {
                            result.typeArguments = parseTypeArguments();
                            break;
                        }
                        else {
                            result.name = parseQualifiedName(result.name);
                        }
                    }
                }
                return finishNode(result);
            }
            function parseTypeArguments() {
                // Move past the <
                nextToken();
                var typeArguments = parseDelimitedList(23 /* JSDocTypeArguments */, parseJSDocType);
                checkForTrailingComma(typeArguments);
                checkForEmptyTypeArgumentList(typeArguments);
                parseExpected(27 /* GreaterThanToken */);
                return typeArguments;
            }
            function checkForEmptyTypeArgumentList(typeArguments) {
                if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) {
                    var start = typeArguments.pos - "<".length;
                    var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length;
                    return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
                }
            }
            function parseQualifiedName(left) {
                var result = createNode(139 /* QualifiedName */, left.pos);
                result.left = left;
                result.right = parseIdentifierName();
                return finishNode(result);
            }
            function parseJSDocRecordType() {
                var result = createNode(265 /* JSDocRecordType */);
                nextToken();
                result.members = parseDelimitedList(24 /* JSDocRecordMembers */, parseJSDocRecordMember);
                checkForTrailingComma(result.members);
                parseExpected(16 /* CloseBraceToken */);
                return finishNode(result);
            }
            function parseJSDocRecordMember() {
                var result = createNode(266 /* JSDocRecordMember */);
                result.name = parseSimplePropertyName();
                if (token === 54 /* ColonToken */) {
                    nextToken();
                    result.type = parseJSDocType();
                }
                return finishNode(result);
            }
            function parseJSDocNonNullableType() {
                var result = createNode(264 /* JSDocNonNullableType */);
                nextToken();
                result.type = parseJSDocType();
                return finishNode(result);
            }
            function parseJSDocTupleType() {
                var result = createNode(262 /* JSDocTupleType */);
                nextToken();
                result.types = parseDelimitedList(25 /* JSDocTupleTypes */, parseJSDocType);
                checkForTrailingComma(result.types);
                parseExpected(20 /* CloseBracketToken */);
                return finishNode(result);
            }
            function checkForTrailingComma(list) {
                if (parseDiagnostics.length === 0 && list.hasTrailingComma) {
                    var start = list.end - ",".length;
                    parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed);
                }
            }
            function parseJSDocUnionType() {
                var result = createNode(261 /* JSDocUnionType */);
                nextToken();
                result.types = parseJSDocTypeList(parseJSDocType());
                parseExpected(18 /* CloseParenToken */);
                return finishNode(result);
            }
            function parseJSDocTypeList(firstType) {
                ts.Debug.assert(!!firstType);
                var types = [];
                types.pos = firstType.pos;
                types.push(firstType);
                while (parseOptional(47 /* BarToken */)) {
                    types.push(parseJSDocType());
                }
                types.end = scanner.getStartPos();
                return types;
            }
            function parseJSDocAllType() {
                var result = createNode(258 /* 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 === 24 /* CommaToken */ ||
                    token === 16 /* CloseBraceToken */ ||
                    token === 18 /* CloseParenToken */ ||
                    token === 27 /* GreaterThanToken */ ||
                    token === 56 /* EqualsToken */ ||
                    token === 47 /* BarToken */) {
                    var result = createNode(259 /* JSDocUnknownType */, pos);
                    return finishNode(result);
                }
                else {
                    var result = createNode(263 /* JSDocNullableType */, pos);
                    result.type = parseJSDocType();
                    return finishNode(result);
                }
            }
            function parseIsolatedJSDocComment(content, start, length) {
                initializeState("file.js", content, 2 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = { languageVariant: 0 /* Standard */, text: content };
                var jsDocComment = parseJSDocCommentWorker(start, length);
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
            function parseJSDocComment(parent, start, length) {
                var saveToken = token;
                var saveParseDiagnosticsLength = parseDiagnostics.length;
                var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
                var comment = parseJSDocCommentWorker(start, length);
                if (comment) {
                    comment.parent = parent;
                }
                token = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
                return comment;
            }
            JSDocParser.parseJSDocComment = parseJSDocComment;
            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 result;
                // Check for /** (JSDoc opening part)
                if (content.charCodeAt(start) === 47 /* slash */ &&
                    content.charCodeAt(start + 1) === 42 /* asterisk */ &&
                    content.charCodeAt(start + 2) === 42 /* asterisk */ &&
                    content.charCodeAt(start + 3) !== 42 /* asterisk */) {
                    // + 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 canParseTag = true;
                        var seenAsterisk = true;
                        nextJSDocToken();
                        while (token !== 1 /* EndOfFileToken */) {
                            switch (token) {
                                case 55 /* AtToken */:
                                    if (canParseTag) {
                                        parseTag();
                                    }
                                    // This will take us to the end of the line, so it's OK to parse a tag on the next pass through the loop
                                    seenAsterisk = false;
                                    break;
                                case 4 /* NewLineTrivia */:
                                    // After a line break, we can parse a tag, and we haven't seen an asterisk on the next line yet
                                    canParseTag = true;
                                    seenAsterisk = false;
                                    break;
                                case 37 /* AsteriskToken */:
                                    if (seenAsterisk) {
                                        // If we've already seen an asterisk, then we can no longer parse a tag on this line
                                        canParseTag = false;
                                    }
                                    // Ignore the first asterisk on a line
                                    seenAsterisk = true;
                                    break;
                                case 69 /* Identifier */:
                                    // Anything else is doc comment text.  We can't do anything with it.  Because it
                                    // wasn't a tag, we can no longer parse a tag on this line until we hit the next
                                    // line break.
                                    canParseTag = false;
                                    break;
                                case 1 /* EndOfFileToken */:
                                    break;
                            }
                            nextJSDocToken();
                        }
                        result = createJSDocComment();
                    });
                }
                return result;
                function createJSDocComment() {
                    if (!tags) {
                        return undefined;
                    }
                    var result = createNode(273 /* JSDocComment */, start);
                    result.tags = tags;
                    return finishNode(result, end);
                }
                function skipWhitespace() {
                    while (token === 5 /* WhitespaceTrivia */ || token === 4 /* NewLineTrivia */) {
                        nextJSDocToken();
                    }
                }
                function parseTag() {
                    ts.Debug.assert(token === 55 /* AtToken */);
                    var atToken = createNode(55 /* AtToken */, scanner.getTokenPos());
                    atToken.end = scanner.getTextPos();
                    nextJSDocToken();
                    var tagName = parseJSDocIdentifierName();
                    if (!tagName) {
                        return;
                    }
                    var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName);
                    addTag(tag);
                }
                function handleTag(atToken, tagName) {
                    if (tagName) {
                        switch (tagName.text) {
                            case "param":
                                return handleParamTag(atToken, tagName);
                            case "return":
                            case "returns":
                                return handleReturnTag(atToken, tagName);
                            case "template":
                                return handleTemplateTag(atToken, tagName);
                            case "type":
                                return handleTypeTag(atToken, tagName);
                            case "typedef":
                                return handleTypedefTag(atToken, tagName);
                        }
                    }
                    return undefined;
                }
                function handleUnknownTag(atToken, tagName) {
                    var result = createNode(274 /* JSDocTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    return finishNode(result);
                }
                function addTag(tag) {
                    if (tag) {
                        if (!tags) {
                            tags = [];
                            tags.pos = tag.pos;
                        }
                        tags.push(tag);
                        tags.end = tag.end;
                    }
                }
                function tryParseTypeExpression() {
                    if (token !== 15 /* OpenBraceToken */) {
                        return undefined;
                    }
                    var typeExpression = parseJSDocTypeExpression();
                    return typeExpression;
                }
                function handleParamTag(atToken, tagName) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespace();
                    var name;
                    var isBracketed;
                    // Looking for something like '[foo]' or 'foo'
                    if (parseOptionalToken(19 /* OpenBracketToken */)) {
                        name = parseJSDocIdentifierName();
                        isBracketed = true;
                        // May have an optional default, e.g. '[foo = 42]'
                        if (parseOptionalToken(56 /* EqualsToken */)) {
                            parseExpression();
                        }
                        parseExpected(20 /* CloseBracketToken */);
                    }
                    else if (ts.tokenIsIdentifierOrKeyword(token)) {
                        name = parseJSDocIdentifierName();
                    }
                    if (!name) {
                        parseErrorAtPosition(scanner.getStartPos(), 0, ts.Diagnostics.Identifier_expected);
                        return undefined;
                    }
                    var preName, postName;
                    if (typeExpression) {
                        postName = name;
                    }
                    else {
                        preName = name;
                    }
                    if (!typeExpression) {
                        typeExpression = tryParseTypeExpression();
                    }
                    var result = createNode(275 /* JSDocParameterTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.preParameterName = preName;
                    result.typeExpression = typeExpression;
                    result.postParameterName = postName;
                    result.isBracketed = isBracketed;
                    return finishNode(result);
                }
                function handleReturnTag(atToken, tagName) {
                    if (ts.forEach(tags, function (t) { return t.kind === 276 /* JSDocReturnTag */; })) {
                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
                    }
                    var result = createNode(276 /* JSDocReturnTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeExpression = tryParseTypeExpression();
                    return finishNode(result);
                }
                function handleTypeTag(atToken, tagName) {
                    if (ts.forEach(tags, function (t) { return t.kind === 277 /* JSDocTypeTag */; })) {
                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
                    }
                    var result = createNode(277 /* JSDocTypeTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeExpression = tryParseTypeExpression();
                    return finishNode(result);
                }
                function handlePropertyTag(atToken, tagName) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespace();
                    var name = parseJSDocIdentifierName();
                    if (!name) {
                        parseErrorAtPosition(scanner.getStartPos(), /*length*/ 0, ts.Diagnostics.Identifier_expected);
                        return undefined;
                    }
                    var result = createNode(280 /* JSDocPropertyTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.name = name;
                    result.typeExpression = typeExpression;
                    return finishNode(result);
                }
                function handleTypedefTag(atToken, tagName) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespace();
                    var typedefTag = createNode(279 /* JSDocTypedefTag */, atToken.pos);
                    typedefTag.atToken = atToken;
                    typedefTag.tagName = tagName;
                    typedefTag.name = parseJSDocIdentifierName();
                    typedefTag.typeExpression = typeExpression;
                    if (typeExpression) {
                        if (typeExpression.type.kind === 267 /* JSDocTypeReference */) {
                            var jsDocTypeReference = typeExpression.type;
                            if (jsDocTypeReference.name.kind === 69 /* Identifier */) {
                                var name_8 = jsDocTypeReference.name;
                                if (name_8.text === "Object") {
                                    typedefTag.jsDocTypeLiteral = scanChildTags();
                                }
                            }
                        }
                        if (!typedefTag.jsDocTypeLiteral) {
                            typedefTag.jsDocTypeLiteral = typeExpression.type;
                        }
                    }
                    else {
                        typedefTag.jsDocTypeLiteral = scanChildTags();
                    }
                    return finishNode(typedefTag);
                    function scanChildTags() {
                        var jsDocTypeLiteral = createNode(281 /* JSDocTypeLiteral */, scanner.getStartPos());
                        var resumePos = scanner.getStartPos();
                        var canParseTag = true;
                        var seenAsterisk = false;
                        var parentTagTerminated = false;
                        while (token !== 1 /* EndOfFileToken */ && !parentTagTerminated) {
                            nextJSDocToken();
                            switch (token) {
                                case 55 /* AtToken */:
                                    if (canParseTag) {
                                        parentTagTerminated = !tryParseChildTag(jsDocTypeLiteral);
                                    }
                                    seenAsterisk = false;
                                    break;
                                case 4 /* NewLineTrivia */:
                                    resumePos = scanner.getStartPos() - 1;
                                    canParseTag = true;
                                    seenAsterisk = false;
                                    break;
                                case 37 /* AsteriskToken */:
                                    if (seenAsterisk) {
                                        canParseTag = false;
                                    }
                                    seenAsterisk = true;
                                    break;
                                case 69 /* Identifier */:
                                    canParseTag = false;
                                case 1 /* EndOfFileToken */:
                                    break;
                            }
                        }
                        scanner.setTextPos(resumePos);
                        return finishNode(jsDocTypeLiteral);
                    }
                }
                function tryParseChildTag(parentTag) {
                    ts.Debug.assert(token === 55 /* AtToken */);
                    var atToken = createNode(55 /* AtToken */, scanner.getStartPos());
                    atToken.end = scanner.getTextPos();
                    nextJSDocToken();
                    var tagName = parseJSDocIdentifierName();
                    if (!tagName) {
                        return false;
                    }
                    switch (tagName.text) {
                        case "type":
                            if (parentTag.jsDocTypeTag) {
                                // already has a @type tag, terminate the parent tag now.
                                return false;
                            }
                            parentTag.jsDocTypeTag = handleTypeTag(atToken, tagName);
                            return true;
                        case "prop":
                        case "property":
                            if (!parentTag.jsDocPropertyTags) {
                                parentTag.jsDocPropertyTags = [];
                            }
                            var propertyTag = handlePropertyTag(atToken, tagName);
                            parentTag.jsDocPropertyTags.push(propertyTag);
                            return true;
                    }
                    return false;
                }
                function handleTemplateTag(atToken, tagName) {
                    if (ts.forEach(tags, function (t) { return t.kind === 278 /* JSDocTemplateTag */; })) {
                        parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text);
                    }
                    // Type parameter list looks like '@template T,U,V'
                    var typeParameters = [];
                    typeParameters.pos = scanner.getStartPos();
                    while (true) {
                        var name_9 = parseJSDocIdentifierName();
                        if (!name_9) {
                            parseErrorAtPosition(scanner.getStartPos(), 0, ts.Diagnostics.Identifier_expected);
                            return undefined;
                        }
                        var typeParameter = createNode(141 /* TypeParameter */, name_9.pos);
                        typeParameter.name = name_9;
                        finishNode(typeParameter);
                        typeParameters.push(typeParameter);
                        if (token === 24 /* CommaToken */) {
                            nextJSDocToken();
                        }
                        else {
                            break;
                        }
                    }
                    var result = createNode(278 /* JSDocTemplateTag */, atToken.pos);
                    result.atToken = atToken;
                    result.tagName = tagName;
                    result.typeParameters = typeParameters;
                    finishNode(result);
                    typeParameters.end = result.end;
                    return result;
                }
                function nextJSDocToken() {
                    return token = scanner.scanJSDocToken();
                }
                function parseJSDocIdentifierName() {
                    return createJSDocIdentifier(ts.tokenIsIdentifierOrKeyword(token));
                }
                function createJSDocIdentifier(isIdentifier) {
                    if (!isIdentifier) {
                        parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected);
                        return undefined;
                    }
                    var pos = scanner.getTokenPos();
                    var end = scanner.getTextPos();
                    var result = createNode(69 /* Identifier */, pos);
                    result.text = 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 (node.jsDocComments) {
                    for (var _i = 0, _a = node.jsDocComments; _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 69 /* 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, n = array.length; i < n; 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) {
    ts.bindTime = 0;
    (function (ModuleInstanceState) {
        ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
        ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
        ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
    })(ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
    var ModuleInstanceState = ts.ModuleInstanceState;
    function getModuleInstanceState(node) {
        // A module is uninstantiated if it contains only
        // 1. interface declarations, type alias declarations
        if (node.kind === 222 /* InterfaceDeclaration */ || node.kind === 223 /* TypeAliasDeclaration */) {
            return 0 /* NonInstantiated */;
        }
        else if (ts.isConstEnumDeclaration(node)) {
            return 2 /* ConstEnumOnly */;
        }
        else if ((node.kind === 230 /* ImportDeclaration */ || node.kind === 229 /* ImportEqualsDeclaration */) && !(node.flags & 1 /* Export */)) {
            return 0 /* NonInstantiated */;
        }
        else if (node.kind === 226 /* 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 === 225 /* ModuleDeclaration */) {
            var body = node.body;
            return body ? getModuleInstanceState(body) : 1 /* Instantiated */;
        }
        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 = {}));
    var binder = createBinder();
    function bindSourceFile(file, options) {
        var start = new Date().getTime();
        binder(file, options);
        ts.bindTime += new Date().getTime() - start;
    }
    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).
        var inStrictMode;
        var symbolCount = 0;
        var Symbol;
        var classifiableNames;
        var unreachableFlow = { flags: 1 /* Unreachable */ };
        var reportedUnreachableFlow = { flags: 1 /* Unreachable */ };
        function bindSourceFile(f, opts) {
            file = f;
            options = opts;
            languageVersion = ts.getEmitScriptTarget(options);
            inStrictMode = !!file.externalModuleIndicator;
            classifiableNames = {};
            symbolCount = 0;
            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 */;
        }
        return bindSourceFile;
        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 = [];
            }
            symbol.declarations.push(node);
            if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) {
                symbol.exports = {};
            }
            if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) {
                symbol.members = {};
            }
            if (symbolFlags & 107455 /* Value */) {
                var valueDeclaration = symbol.valueDeclaration;
                if (!valueDeclaration ||
                    (valueDeclaration.kind !== node.kind && valueDeclaration.kind === 225 /* 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.name) {
                if (ts.isAmbientModule(node)) {
                    return ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + node.name.text + "\"";
                }
                if (node.name.kind === 140 /* 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.kind)) {
                        return nameExpression.text;
                    }
                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
                    return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
                }
                return node.name.text;
            }
            switch (node.kind) {
                case 148 /* Constructor */:
                    return "__constructor";
                case 156 /* FunctionType */:
                case 151 /* CallSignature */:
                    return "__call";
                case 157 /* ConstructorType */:
                case 152 /* ConstructSignature */:
                    return "__new";
                case 153 /* IndexSignature */:
                    return "__index";
                case 236 /* ExportDeclaration */:
                    return "__export";
                case 235 /* ExportAssignment */:
                    return node.isExportEquals ? "export=" : "default";
                case 187 /* BinaryExpression */:
                    switch (ts.getSpecialPropertyAssignmentKind(node)) {
                        case 2 /* ModuleExports */:
                            // module.exports = ...
                            return "export=";
                        case 1 /* ExportsProperty */:
                        case 4 /* ThisProperty */:
                            // exports.x = ... or this.y = ...
                            return node.left.name.text;
                        case 3 /* PrototypeProperty */:
                            // className.prototype.methodName = ...
                            return node.left.expression.name.text;
                    }
                    ts.Debug.fail("Unknown binary declaration kind");
                    break;
                case 220 /* FunctionDeclaration */:
                case 221 /* ClassDeclaration */:
                    return node.flags & 512 /* Default */ ? "default" : undefined;
                case 269 /* JSDocFunctionType */:
                    return ts.isJSDocConstructSignature(node) ? "__new" : "__call";
                case 142 /* 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 === 269 /* JSDocFunctionType */);
                    var functionType = node.parent;
                    var index = ts.indexOf(functionType.parameters, node);
                    return "p" + index;
                case 279 /* JSDocTypedefTag */:
                    var parentNode = node.parent && node.parent.parent;
                    var nameFromParentNode = void 0;
                    if (parentNode && parentNode.kind === 200 /* VariableStatement */) {
                        if (parentNode.declarationList.declarations.length > 0) {
                            var nameIdentifier = parentNode.declarationList.declarations[0].name;
                            if (nameIdentifier.kind === 69 /* Identifier */) {
                                nameFromParentNode = nameIdentifier.text;
                            }
                        }
                    }
                    return nameFromParentNode;
            }
        }
        function getDisplayName(node) {
            return node.name ? ts.declarationNameToString(node.name) : 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) {
            ts.Debug.assert(!ts.hasDynamicName(node));
            var isDefaultExport = node.flags & 512 /* Default */;
            // The exported symbol for an export default function/class node is always named "default"
            var name = isDefaultExport && parent ? "default" : getDeclarationName(node);
            var symbol;
            if (name !== undefined) {
                // 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.
                //
                // 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 = ts.hasProperty(symbolTable, name)
                    ? symbolTable[name]
                    : (symbolTable[name] = createSymbol(0 /* None */, name));
                if (name && (includes & 788448 /* Classifiable */)) {
                    classifiableNames[name] = name;
                }
                if (symbol.flags & excludes) {
                    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;
                    ts.forEach(symbol.declarations, function (declaration) {
                        if (declaration.flags & 512 /* Default */) {
                            message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                        }
                    });
                    ts.forEach(symbol.declarations, function (declaration) {
                        file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message_1, getDisplayName(declaration)));
                    });
                    file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message_1, getDisplayName(node)));
                    symbol = createSymbol(0 /* None */, name);
                }
            }
            else {
                symbol = createSymbol(0 /* None */, "__missing");
            }
            addDeclarationToSymbol(symbol, node, includes);
            symbol.parent = parent;
            return symbol;
        }
        function declareModuleMember(node, symbolFlags, symbolExcludes) {
            var hasExportModifier = ts.getCombinedNodeFlags(node) & 1 /* Export */;
            if (symbolFlags & 8388608 /* Alias */) {
                if (node.kind === 238 /* ExportSpecifier */ || (node.kind === 229 /* ImportEqualsDeclaration */ && hasExportModifier)) {
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                }
                else {
                    return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
                }
            }
            else {
                // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
                // ExportType, or ExportContainer 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 (!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 8192 /* ExportContext */)) {
                    var exportKind = (symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) |
                        (symbolFlags & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) |
                        (symbolFlags & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0);
                    var local = declareSymbol(container.locals, 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, 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 = {};
                }
                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.getImmediatelyInvokedFunctionExpression(node);
                // An 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 */) {
                        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)
                // Reset all emit helper flags on node (for incremental scenarios)
                node.flags &= ~4030464 /* ReachabilityAndEmitFlags */;
                if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
                    node.flags |= 32768 /* HasImplicitReturn */;
                    if (hasExplicitReturn)
                        node.flags |= 65536 /* HasExplicitReturn */;
                }
                if (node.kind === 256 /* 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 | 16384 /* ContainsThis */ : node.flags & ~16384 /* ContainsThis */;
            }
            else {
                bindChildren(node);
            }
            container = saveContainer;
            blockScopeContainer = savedBlockScopeContainer;
        }
        function bindChildren(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.isInJavaScriptFile(node) && node.jsDocComments) {
                for (var _i = 0, _a = node.jsDocComments; _i < _a.length; _i++) {
                    var jsDocComment = _a[_i];
                    bind(jsDocComment);
                }
            }
            if (checkUnreachable(node)) {
                ts.forEachChild(node, bind);
                return;
            }
            switch (node.kind) {
                case 205 /* WhileStatement */:
                    bindWhileStatement(node);
                    break;
                case 204 /* DoStatement */:
                    bindDoStatement(node);
                    break;
                case 206 /* ForStatement */:
                    bindForStatement(node);
                    break;
                case 207 /* ForInStatement */:
                case 208 /* ForOfStatement */:
                    bindForInOrForOfStatement(node);
                    break;
                case 203 /* IfStatement */:
                    bindIfStatement(node);
                    break;
                case 211 /* ReturnStatement */:
                case 215 /* ThrowStatement */:
                    bindReturnOrThrow(node);
                    break;
                case 210 /* BreakStatement */:
                case 209 /* ContinueStatement */:
                    bindBreakOrContinueStatement(node);
                    break;
                case 216 /* TryStatement */:
                    bindTryStatement(node);
                    break;
                case 213 /* SwitchStatement */:
                    bindSwitchStatement(node);
                    break;
                case 227 /* CaseBlock */:
                    bindCaseBlock(node);
                    break;
                case 249 /* CaseClause */:
                    bindCaseClause(node);
                    break;
                case 214 /* LabeledStatement */:
                    bindLabeledStatement(node);
                    break;
                case 185 /* PrefixUnaryExpression */:
                    bindPrefixUnaryExpressionFlow(node);
                    break;
                case 187 /* BinaryExpression */:
                    bindBinaryExpressionFlow(node);
                    break;
                case 181 /* DeleteExpression */:
                    bindDeleteExpressionFlow(node);
                    break;
                case 188 /* ConditionalExpression */:
                    bindConditionalExpressionFlow(node);
                    break;
                case 218 /* VariableDeclaration */:
                    bindVariableDeclarationFlow(node);
                    break;
                case 174 /* CallExpression */:
                    bindCallExpressionFlow(node);
                    break;
                default:
                    ts.forEachChild(node, bind);
                    break;
            }
        }
        function isNarrowingExpression(expr) {
            switch (expr.kind) {
                case 69 /* Identifier */:
                case 97 /* ThisKeyword */:
                case 172 /* PropertyAccessExpression */:
                    return isNarrowableReference(expr);
                case 174 /* CallExpression */:
                    return hasNarrowableArgument(expr);
                case 178 /* ParenthesizedExpression */:
                    return isNarrowingExpression(expr.expression);
                case 187 /* BinaryExpression */:
                    return isNarrowingBinaryExpression(expr);
                case 185 /* PrefixUnaryExpression */:
                    return expr.operator === 49 /* ExclamationToken */ && isNarrowingExpression(expr.operand);
            }
            return false;
        }
        function isNarrowableReference(expr) {
            return expr.kind === 69 /* Identifier */ ||
                expr.kind === 97 /* ThisKeyword */ ||
                expr.kind === 172 /* 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 === 172 /* PropertyAccessExpression */ &&
                isNarrowableReference(expr.expression.expression)) {
                return true;
            }
            return false;
        }
        function isNarrowingNullCheckOperands(expr1, expr2) {
            return (expr1.kind === 93 /* NullKeyword */ || expr1.kind === 69 /* Identifier */ && expr1.text === "undefined") && isNarrowableOperand(expr2);
        }
        function isNarrowingTypeofOperands(expr1, expr2) {
            return expr1.kind === 182 /* TypeOfExpression */ && isNarrowableOperand(expr1.expression) && expr2.kind === 9 /* StringLiteral */;
        }
        function isNarrowingDiscriminant(expr) {
            return expr.kind === 172 /* PropertyAccessExpression */ && isNarrowableReference(expr.expression);
        }
        function isNarrowingBinaryExpression(expr) {
            switch (expr.operatorToken.kind) {
                case 56 /* EqualsToken */:
                    return isNarrowableReference(expr.left);
                case 30 /* EqualsEqualsToken */:
                case 31 /* ExclamationEqualsToken */:
                case 32 /* EqualsEqualsEqualsToken */:
                case 33 /* ExclamationEqualsEqualsToken */:
                    return isNarrowingNullCheckOperands(expr.right, expr.left) || isNarrowingNullCheckOperands(expr.left, expr.right) ||
                        isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right) ||
                        isNarrowingDiscriminant(expr.left) || isNarrowingDiscriminant(expr.right);
                case 91 /* InstanceOfKeyword */:
                    return isNarrowableOperand(expr.left);
                case 24 /* CommaToken */:
                    return isNarrowingExpression(expr.right);
            }
            return false;
        }
        function isNarrowableOperand(expr) {
            switch (expr.kind) {
                case 178 /* ParenthesizedExpression */:
                    return isNarrowableOperand(expr.expression);
                case 187 /* BinaryExpression */:
                    switch (expr.operatorToken.kind) {
                        case 56 /* EqualsToken */:
                            return isNarrowableOperand(expr.left);
                        case 24 /* CommaToken */:
                            return isNarrowableOperand(expr.right);
                    }
            }
            return isNarrowableReference(expr);
        }
        function isNarrowingSwitchStatement(switchStatement) {
            var expr = switchStatement.expression;
            return expr.kind === 172 /* PropertyAccessExpression */ && isNarrowableReference(expr.expression);
        }
        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 & 256 /* Referenced */ ? 512 /* Shared */ : 256 /* 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 === 99 /* TrueKeyword */ && flags & 64 /* FalseCondition */ ||
                expression.kind === 84 /* 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 (!isNarrowingSwitchStatement(switchStatement)) {
                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 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 203 /* IfStatement */:
                case 205 /* WhileStatement */:
                case 204 /* DoStatement */:
                    return parent.expression === node;
                case 206 /* ForStatement */:
                case 188 /* ConditionalExpression */:
                    return parent.condition === node;
            }
            return false;
        }
        function isLogicalExpression(node) {
            while (true) {
                if (node.kind === 178 /* ParenthesizedExpression */) {
                    node = node.expression;
                }
                else if (node.kind === 185 /* PrefixUnaryExpression */ && node.operator === 49 /* ExclamationToken */) {
                    node = node.operand;
                }
                else {
                    return node.kind === 187 /* BinaryExpression */ && (node.operatorToken.kind === 51 /* AmpersandAmpersandToken */ ||
                        node.operatorToken.kind === 52 /* BarBarToken */);
                }
            }
        }
        function isTopLevelLogicalExpression(node) {
            while (node.parent.kind === 178 /* ParenthesizedExpression */ ||
                node.parent.kind === 185 /* PrefixUnaryExpression */ &&
                    node.parent.operator === 49 /* 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 preConditionLabel = createBranchLabel();
            var postDoLabel = 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;
            bind(node.expression);
            addAntecedent(postLoopLabel, currentFlow);
            bind(node.initializer);
            if (node.initializer.kind !== 219 /* 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 === 211 /* 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 === 210 /* BreakStatement */ ? breakTarget : continueTarget;
            if (flowLabel) {
                addAntecedent(flowLabel, currentFlow);
                currentFlow = unreachableFlow;
            }
        }
        function bindBreakOrContinueStatement(node) {
            bind(node.label);
            if (node.label) {
                var activeLabel = findActiveLabel(node.label.text);
                if (activeLabel) {
                    activeLabel.referenced = true;
                    bindbreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
                }
            }
            else {
                bindbreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
            }
        }
        function bindTryStatement(node) {
            var postFinallyLabel = createBranchLabel();
            var preTryFlow = currentFlow;
            // TODO: Every statement in try block is potentially an exit point!
            bind(node.tryBlock);
            addAntecedent(postFinallyLabel, currentFlow);
            if (node.catchClause) {
                currentFlow = preTryFlow;
                bind(node.catchClause);
                addAntecedent(postFinallyLabel, currentFlow);
            }
            if (node.finallyBlock) {
                currentFlow = preTryFlow;
                bind(node.finallyBlock);
            }
            currentFlow = finishFlowLabel(postFinallyLabel);
        }
        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 === 250 /* 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 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);
                }
            }
        }
        function bindCaseClause(node) {
            var saveCurrentFlow = currentFlow;
            currentFlow = preSwitchCaseFlow;
            bind(node.expression);
            currentFlow = saveCurrentFlow;
            ts.forEach(node.statements, bind);
        }
        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.text, postStatementLabel, preStatementLabel);
            bind(node.statement);
            popActiveLabel();
            if (!activeLabel.referenced && !options.allowUnusedLabels) {
                file.bindDiagnostics.push(ts.createDiagnosticForNode(node.label, ts.Diagnostics.Unused_label));
            }
            addAntecedent(postStatementLabel, currentFlow);
            currentFlow = finishFlowLabel(postStatementLabel);
        }
        function bindDestructuringTargetFlow(node) {
            if (node.kind === 187 /* BinaryExpression */ && node.operatorToken.kind === 56 /* EqualsToken */) {
                bindAssignmentTargetFlow(node.left);
            }
            else {
                bindAssignmentTargetFlow(node);
            }
        }
        function bindAssignmentTargetFlow(node) {
            if (isNarrowableReference(node)) {
                currentFlow = createFlowAssignment(currentFlow, node);
            }
            else if (node.kind === 170 /* ArrayLiteralExpression */) {
                for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                    var e = _a[_i];
                    if (e.kind === 191 /* SpreadElementExpression */) {
                        bindAssignmentTargetFlow(e.expression);
                    }
                    else {
                        bindDestructuringTargetFlow(e);
                    }
                }
            }
            else if (node.kind === 171 /* ObjectLiteralExpression */) {
                for (var _b = 0, _c = node.properties; _b < _c.length; _b++) {
                    var p = _c[_b];
                    if (p.kind === 253 /* PropertyAssignment */) {
                        bindDestructuringTargetFlow(p.initializer);
                    }
                    else if (p.kind === 254 /* ShorthandPropertyAssignment */) {
                        bindAssignmentTargetFlow(p.name);
                    }
                }
            }
        }
        function bindLogicalExpression(node, trueTarget, falseTarget) {
            var preRightLabel = createBranchLabel();
            if (node.operatorToken.kind === 51 /* 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 === 49 /* ExclamationToken */) {
                var saveTrueTarget = currentTrueTarget;
                currentTrueTarget = currentFalseTarget;
                currentFalseTarget = saveTrueTarget;
                ts.forEachChild(node, bind);
                currentFalseTarget = currentTrueTarget;
                currentTrueTarget = saveTrueTarget;
            }
            else {
                ts.forEachChild(node, bind);
            }
        }
        function bindBinaryExpressionFlow(node) {
            var operator = node.operatorToken.kind;
            if (operator === 51 /* AmpersandAmpersandToken */ || operator === 52 /* BarBarToken */) {
                if (isTopLevelLogicalExpression(node)) {
                    var postExpressionLabel = createBranchLabel();
                    bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
                    currentFlow = finishFlowLabel(postExpressionLabel);
                }
                else {
                    bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
                }
            }
            else {
                ts.forEachChild(node, bind);
                if (operator === 56 /* EqualsToken */ && !ts.isAssignmentTarget(node)) {
                    bindAssignmentTargetFlow(node.left);
                }
            }
        }
        function bindDeleteExpressionFlow(node) {
            ts.forEachChild(node, bind);
            if (node.expression.kind === 172 /* 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.whenTrue);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(falseLabel);
            bind(node.whenFalse);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(postExpressionLabel);
        }
        function bindInitializedVariableFlow(node) {
            var name = node.name;
            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) {
            ts.forEachChild(node, bind);
            if (node.initializer || node.parent.parent.kind === 207 /* ForInStatement */ || node.parent.parent.kind === 208 /* ForOfStatement */) {
                bindInitializedVariableFlow(node);
            }
        }
        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 === 178 /* ParenthesizedExpression */) {
                expr = expr.expression;
            }
            if (expr.kind === 179 /* FunctionExpression */ || expr.kind === 180 /* ArrowFunction */) {
                ts.forEach(node.typeArguments, bind);
                ts.forEach(node.arguments, bind);
                bind(node.expression);
            }
            else {
                ts.forEachChild(node, bind);
            }
        }
        function getContainerFlags(node) {
            switch (node.kind) {
                case 192 /* ClassExpression */:
                case 221 /* ClassDeclaration */:
                case 224 /* EnumDeclaration */:
                case 171 /* ObjectLiteralExpression */:
                case 159 /* TypeLiteral */:
                case 281 /* JSDocTypeLiteral */:
                case 265 /* JSDocRecordType */:
                    return 1 /* IsContainer */;
                case 222 /* InterfaceDeclaration */:
                    return 1 /* IsContainer */ | 64 /* IsInterface */;
                case 269 /* JSDocFunctionType */:
                case 225 /* ModuleDeclaration */:
                case 223 /* TypeAliasDeclaration */:
                    return 1 /* IsContainer */ | 32 /* HasLocals */;
                case 256 /* SourceFile */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */;
                case 148 /* Constructor */:
                case 220 /* FunctionDeclaration */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 151 /* CallSignature */:
                case 152 /* ConstructSignature */:
                case 153 /* IndexSignature */:
                case 156 /* FunctionType */:
                case 157 /* ConstructorType */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */;
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */;
                case 226 /* ModuleBlock */:
                    return 4 /* IsControlFlowContainer */;
                case 145 /* PropertyDeclaration */:
                    return node.initializer ? 4 /* IsControlFlowContainer */ : 0;
                case 252 /* CatchClause */:
                case 206 /* ForStatement */:
                case 207 /* ForInStatement */:
                case 208 /* ForOfStatement */:
                case 227 /* CaseBlock */:
                    return 2 /* IsBlockScopedContainer */;
                case 199 /* 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) {
            // Just call this directly so that the return type of this function stays "void".
            return declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
        }
        function declareSymbolAndAddToSymbolTableWorker(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 225 /* ModuleDeclaration */:
                    return declareModuleMember(node, symbolFlags, symbolExcludes);
                case 256 /* SourceFile */:
                    return declareSourceFileMember(node, symbolFlags, symbolExcludes);
                case 192 /* ClassExpression */:
                case 221 /* ClassDeclaration */:
                    return declareClassMember(node, symbolFlags, symbolExcludes);
                case 224 /* EnumDeclaration */:
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                case 159 /* TypeLiteral */:
                case 171 /* ObjectLiteralExpression */:
                case 222 /* InterfaceDeclaration */:
                case 265 /* JSDocRecordType */:
                case 281 /* JSDocTypeLiteral */:
                    // 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 156 /* FunctionType */:
                case 157 /* ConstructorType */:
                case 151 /* CallSignature */:
                case 152 /* ConstructSignature */:
                case 153 /* IndexSignature */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 148 /* Constructor */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                case 269 /* JSDocFunctionType */:
                case 223 /* TypeAliasDeclaration */:
                    // 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 node.flags & 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, undefined, node, symbolFlags, symbolExcludes);
        }
        function hasExportDeclarations(node) {
            var body = node.kind === 256 /* SourceFile */ ? node : node.body;
            if (body && (body.kind === 256 /* SourceFile */ || body.kind === 226 /* ModuleBlock */)) {
                for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
                    var stat = _a[_i];
                    if (stat.kind === 236 /* ExportDeclaration */ || stat.kind === 235 /* 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 |= 8192 /* ExportContext */;
            }
            else {
                node.flags &= ~8192 /* ExportContext */;
            }
        }
        function bindModuleDeclaration(node) {
            setExportContextFlag(node);
            if (ts.isAmbientModule(node)) {
                if (node.flags & 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)) {
                    declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */);
                }
                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 = getModuleInstanceState(node);
                if (state === 0 /* NonInstantiated */) {
                    declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */);
                    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 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");
            addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
            typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a);
            var _a;
        }
        function bindObjectLiteralExpression(node) {
            var ElementKind;
            (function (ElementKind) {
                ElementKind[ElementKind["Property"] = 1] = "Property";
                ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
            })(ElementKind || (ElementKind = {}));
            if (inStrictMode) {
                var seen = {};
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (prop.name.kind !== 69 /* 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 === 253 /* PropertyAssignment */ || prop.kind === 254 /* ShorthandPropertyAssignment */ || prop.kind === 147 /* MethodDeclaration */
                        ? 1 /* Property */
                        : 2 /* Accessor */;
                    var existingKind = seen[identifier.text];
                    if (!existingKind) {
                        seen[identifier.text] = currentKind;
                        continue;
                    }
                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
                        var span = ts.getErrorSpanForNode(file, identifier);
                        file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
                    }
                }
            }
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object");
        }
        function bindAnonymousDeclaration(node, symbolFlags, name) {
            var symbol = createSymbol(symbolFlags, name);
            addDeclarationToSymbol(symbol, node, symbolFlags);
        }
        function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
            switch (blockScopeContainer.kind) {
                case 225 /* ModuleDeclaration */:
                    declareModuleMember(node, symbolFlags, symbolExcludes);
                    break;
                case 256 /* SourceFile */:
                    if (ts.isExternalModule(container)) {
                        declareModuleMember(node, symbolFlags, symbolExcludes);
                        break;
                    }
                // fall through.
                default:
                    if (!blockScopeContainer.locals) {
                        blockScopeContainer.locals = {};
                        addToContainerChain(blockScopeContainer);
                    }
                    declareSymbol(blockScopeContainer.locals, 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 >= 106 /* FirstFutureReservedWord */ &&
                node.originalKeywordKind <= 114 /* 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(ts.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 === 69 /* 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 = ts.getErrorSpanForNode(file, node.expression);
                file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
            }
        }
        function isEvalOrArgumentsIdentifier(node) {
            return node.kind === 69 /* Identifier */ &&
                (node.text === "eval" || node.text === "arguments");
        }
        function checkStrictModeEvalOrArguments(contextNode, name) {
            if (name && name.kind === 69 /* 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 = ts.getErrorSpanForNode(file, name);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
                }
            }
        }
        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 /* ES6 */) {
                // Report error if function is not top level function declaration
                if (blockScopeContainer.kind !== 256 /* SourceFile */ &&
                    blockScopeContainer.kind !== 225 /* 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.isOctalLiteral) {
                file.bindDiagnostics.push(ts.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 === 41 /* PlusPlusToken */ || node.operator === 42 /* 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 getDestructuringParameterName(node) {
            return "__" + ts.indexOf(node.parent.parameters, node);
        }
        function bind(node) {
            if (!node) {
                return;
            }
            node.parent = parent;
            var saveInStrictMode = inStrictMode;
            // 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 > 138 /* LastToken */) {
                var saveParent = parent;
                parent = node;
                var containerFlags = getContainerFlags(node);
                if (containerFlags === 0 /* None */) {
                    bindChildren(node);
                }
                else {
                    bindContainer(node, containerFlags);
                }
                parent = saveParent;
            }
            inStrictMode = saveInStrictMode;
        }
        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 69 /* Identifier */:
                case 97 /* ThisKeyword */:
                    if (currentFlow && (ts.isExpression(node) || parent.kind === 254 /* ShorthandPropertyAssignment */)) {
                        node.flowNode = currentFlow;
                    }
                    return checkStrictModeIdentifier(node);
                case 172 /* PropertyAccessExpression */:
                    if (currentFlow && isNarrowableReference(node)) {
                        node.flowNode = currentFlow;
                    }
                    break;
                case 187 /* BinaryExpression */:
                    if (ts.isInJavaScriptFile(node)) {
                        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 0 /* None */:
                                // Nothing to do
                                break;
                            default:
                                ts.Debug.fail("Unknown special property assignment kind");
                        }
                    }
                    return checkStrictModeBinaryExpression(node);
                case 252 /* CatchClause */:
                    return checkStrictModeCatchClause(node);
                case 181 /* DeleteExpression */:
                    return checkStrictModeDeleteExpression(node);
                case 8 /* NumericLiteral */:
                    return checkStrictModeNumericLiteral(node);
                case 186 /* PostfixUnaryExpression */:
                    return checkStrictModePostfixUnaryExpression(node);
                case 185 /* PrefixUnaryExpression */:
                    return checkStrictModePrefixUnaryExpression(node);
                case 212 /* WithStatement */:
                    return checkStrictModeWithStatement(node);
                case 165 /* ThisType */:
                    seenThisKeyword = true;
                    return;
                case 154 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 141 /* TypeParameter */:
                    return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */);
                case 142 /* Parameter */:
                    return bindParameter(node);
                case 218 /* VariableDeclaration */:
                case 169 /* BindingElement */:
                    return bindVariableDeclarationOrBindingElement(node);
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 266 /* JSDocRecordMember */:
                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
                case 280 /* JSDocPropertyTag */:
                    return bindJSDocProperty(node);
                case 253 /* PropertyAssignment */:
                case 254 /* ShorthandPropertyAssignment */:
                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */);
                case 255 /* EnumMember */:
                    return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */);
                case 247 /* JsxSpreadAttribute */:
                    emitFlags |= 1073741824 /* HasJsxSpreadAttribute */;
                    return;
                case 151 /* CallSignature */:
                case 152 /* ConstructSignature */:
                case 153 /* IndexSignature */:
                    return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
                case 147 /* MethodDeclaration */:
                case 146 /* 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 ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 99263 /* MethodExcludes */);
                case 220 /* FunctionDeclaration */:
                    return bindFunctionDeclaration(node);
                case 148 /* Constructor */:
                    return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
                case 149 /* GetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */);
                case 150 /* SetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */);
                case 156 /* FunctionType */:
                case 157 /* ConstructorType */:
                case 269 /* JSDocFunctionType */:
                    return bindFunctionOrConstructorType(node);
                case 159 /* TypeLiteral */:
                case 281 /* JSDocTypeLiteral */:
                case 265 /* JSDocRecordType */:
                    return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type");
                case 171 /* ObjectLiteralExpression */:
                    return bindObjectLiteralExpression(node);
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    return bindFunctionExpression(node);
                case 174 /* CallExpression */:
                    if (ts.isInJavaScriptFile(node)) {
                        bindCallExpression(node);
                    }
                    break;
                // Members of classes, interfaces, and modules
                case 192 /* ClassExpression */:
                case 221 /* ClassDeclaration */:
                    // All classes are automatically in strict mode in ES6.
                    inStrictMode = true;
                    return bindClassLikeDeclaration(node);
                case 222 /* InterfaceDeclaration */:
                    return bindBlockScopedDeclaration(node, 64 /* Interface */, 792960 /* InterfaceExcludes */);
                case 279 /* JSDocTypedefTag */:
                case 223 /* TypeAliasDeclaration */:
                    return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */);
                case 224 /* EnumDeclaration */:
                    return bindEnumDeclaration(node);
                case 225 /* ModuleDeclaration */:
                    return bindModuleDeclaration(node);
                // Imports and exports
                case 229 /* ImportEqualsDeclaration */:
                case 232 /* NamespaceImport */:
                case 234 /* ImportSpecifier */:
                case 238 /* ExportSpecifier */:
                    return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
                case 228 /* NamespaceExportDeclaration */:
                    return bindNamespaceExportDeclaration(node);
                case 231 /* ImportClause */:
                    return bindImportClause(node);
                case 236 /* ExportDeclaration */:
                    return bindExportDeclaration(node);
                case 235 /* ExportAssignment */:
                    return bindExportAssignment(node);
                case 256 /* SourceFile */:
                    updateStrictModeStatementList(node.statements);
                    return bindSourceFileIfExternalModule();
                case 199 /* Block */:
                    if (!ts.isFunctionLike(node.parent)) {
                        return;
                    }
                // Fall through
                case 226 /* ModuleBlock */:
                    return updateStrictModeStatementList(node.statements);
            }
        }
        function checkTypePredicate(node) {
            var parameterName = node.parameterName, type = node.type;
            if (parameterName && parameterName.kind === 69 /* Identifier */) {
                checkStrictModeIdentifier(parameterName);
            }
            if (parameterName && parameterName.kind === 165 /* 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) {
            var boundExpression = node.kind === 235 /* ExportAssignment */ ? node.expression : node.right;
            if (!container.symbol || !container.symbol.exports) {
                // Export assignment in some sort of block construct
                bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node));
            }
            else if (boundExpression.kind === 69 /* Identifier */ && node.kind === 235 /* ExportAssignment */) {
                // An export default clause with an identifier exports all meanings of that identifier
                declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
            }
            else {
                // An export default clause with an expression exports a value
                declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */);
            }
        }
        function bindNamespaceExportDeclaration(node) {
            if (node.modifiers && node.modifiers.length) {
                file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here));
            }
            if (node.parent.kind !== 256 /* SourceFile */) {
                file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level));
                return;
            }
            else {
                var parent_6 = node.parent;
                if (!ts.isExternalModule(parent_6)) {
                    file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files));
                    return;
                }
                if (!parent_6.isDeclarationFile) {
                    file.bindDiagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files));
                    return;
                }
            }
            file.symbol.globalExports = file.symbol.globalExports || {};
            declareSymbol(file.symbol.globalExports, file.symbol, node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
        }
        function bindExportDeclaration(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export * in some sort of block construct
                bindAnonymousDeclaration(node, 1073741824 /* ExportStar */, getDeclarationName(node));
            }
            else if (!node.exportClause) {
                // All export * declarations are collected in an __export symbol
                declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */);
            }
        }
        function bindImportClause(node) {
            if (node.name) {
                declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */);
            }
        }
        function setCommonJsModuleIndicator(node) {
            if (!file.commonJsModuleIndicator) {
                file.commonJsModuleIndicator = node;
                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 */ | 7340032 /* Export */, 0 /* None */);
        }
        function bindModuleExportsAssignment(node) {
            // 'module.exports = expr' assignment
            setCommonJsModuleIndicator(node);
            declareSymbol(file.symbol.exports, file.symbol, node, 4 /* Property */ | 7340032 /* Export */ | 512 /* ValueModule */, 0 /* None */);
        }
        function bindThisPropertyAssignment(node) {
            // Declare a 'member' in case it turns out the container was an ES5 class or ES6 constructor
            var assignee;
            if (container.kind === 220 /* FunctionDeclaration */ || container.kind === 220 /* FunctionDeclaration */) {
                assignee = container;
            }
            else if (container.kind === 148 /* Constructor */) {
                assignee = container.parent;
            }
            else {
                return;
            }
            assignee.symbol.members = assignee.symbol.members || {};
            // It's acceptable for multiple 'this' assignments of the same identifier to occur
            declareSymbol(assignee.symbol.members, assignee.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */);
        }
        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;
            var funcSymbol = container.locals[constructorFunction.text];
            if (!funcSymbol || !(funcSymbol.flags & 16 /* Function */ || ts.isDeclarationOfFunctionExpression(funcSymbol))) {
                return;
            }
            // Set up the members collection if it doesn't exist already
            if (!funcSymbol.members) {
                funcSymbol.members = {};
            }
            // Declare the method/property
            declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, 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 (!ts.isDeclarationFile(file) && !ts.isInAmbientContext(node)) {
                if (ts.getClassExtendsHeritageClauseElement(node) !== undefined) {
                    emitFlags |= 262144 /* HasClassExtends */;
                }
                if (ts.nodeIsDecorated(node)) {
                    emitFlags |= 524288 /* HasDecorators */;
                }
            }
            if (node.kind === 221 /* ClassDeclaration */) {
                bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */);
            }
            else {
                var bindingName = node.name ? node.name.text : "__class";
                bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
                // Add name of class expression into the map for semantic classifier
                if (node.name) {
                    classifiableNames[node.name.text] = node.name.text;
                }
            }
            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 */ | 134217728 /* Prototype */, "prototype");
            if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
                if (node.name) {
                    node.name.parent = node;
                }
                file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
            }
            symbol.exports[prototypeSymbol.name] = 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 (!ts.isDeclarationFile(file) &&
                !ts.isInAmbientContext(node) &&
                ts.nodeIsDecorated(node)) {
                emitFlags |= (524288 /* HasDecorators */ | 1048576 /* HasParamDecorators */);
            }
            if (inStrictMode) {
                // 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 */, getDestructuringParameterName(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 ? 536870912 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
            }
        }
        function bindFunctionDeclaration(node) {
            if (!ts.isDeclarationFile(file) && !ts.isInAmbientContext(node)) {
                if (ts.isAsyncFunctionLike(node)) {
                    emitFlags |= 2097152 /* HasAsyncFunctions */;
                }
            }
            checkStrictModeFunctionName(node);
            if (inStrictMode) {
                checkStrictModeFunctionDeclaration(node);
                bindBlockScopedDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */);
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */);
            }
        }
        function bindFunctionExpression(node) {
            if (!ts.isDeclarationFile(file) && !ts.isInAmbientContext(node)) {
                if (ts.isAsyncFunctionLike(node)) {
                    emitFlags |= 2097152 /* HasAsyncFunctions */;
                }
            }
            if (currentFlow) {
                node.flowNode = currentFlow;
            }
            checkStrictModeFunctionName(node);
            var bindingName = node.name ? node.name.text : "__function";
            return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
        }
        function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
            if (!ts.isDeclarationFile(file) && !ts.isInAmbientContext(node)) {
                if (ts.isAsyncFunctionLike(node)) {
                    emitFlags |= 2097152 /* HasAsyncFunctions */;
                }
                if (ts.nodeIsDecorated(node)) {
                    emitFlags |= 524288 /* HasDecorators */;
                }
            }
            return ts.hasDynamicName(node)
                ? bindAnonymousDeclaration(node, symbolFlags, "__computed")
                : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function bindJSDocProperty(node) {
            return declareSymbolAndAddToSymbolTable(node, 4 /* Property */, 0 /* PropertyExcludes */);
        }
        // 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.isStatement(node) && node.kind !== 201 /* EmptyStatement */) ||
                    // report error on class declarations
                    node.kind === 221 /* ClassDeclaration */ ||
                    // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
                    (node.kind === 225 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) ||
                    // report error on regular enums and const enums if preserveConstEnums is set
                    (node.kind === 224 /* 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 !== 200 /* VariableStatement */ ||
                            ts.getCombinedNodeFlags(node.declarationList) & 3072 /* BlockScoped */ ||
                            ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; }));
                    if (reportUnreachableCode) {
                        errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected);
                    }
                }
            }
            return true;
        }
    }
})(ts || (ts = {}));
/// <reference path="binder.ts"/>
/* @internal */
var ts;
(function (ts) {
    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;
    ts.checkTime = 0;
    function getSymbolId(symbol) {
        if (!symbol.id) {
            symbol.id = nextSymbolId;
            nextSymbolId++;
        }
        return symbol.id;
    }
    ts.getSymbolId = getSymbolId;
    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 Symbol = ts.objectAllocator.getSymbolConstructor();
        var Type = ts.objectAllocator.getTypeConstructor();
        var Signature = ts.objectAllocator.getSignatureConstructor();
        var typeCount = 0;
        var symbolCount = 0;
        var emptyArray = [];
        var emptySymbols = {};
        var compilerOptions = host.getCompilerOptions();
        var languageVersion = compilerOptions.target || 0 /* ES3 */;
        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;
        var emitResolver = createResolver();
        var undefinedSymbol = createSymbol(4 /* Property */ | 67108864 /* Transient */, "undefined");
        undefinedSymbol.declarations = [];
        var argumentsSymbol = createSymbol(4 /* Property */ | 67108864 /* Transient */, "arguments");
        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; },
            getDiagnostics: getDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getTypeOfSymbolAtLocation: getTypeOfSymbolAtLocation,
            getSymbolsOfParameterPropertyDeclaration: getSymbolsOfParameterPropertyDeclaration,
            getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
            getPropertiesOfType: getPropertiesOfType,
            getPropertyOfType: getPropertyOfType,
            getSignaturesOfType: getSignaturesOfType,
            getIndexTypeOfType: getIndexTypeOfType,
            getBaseTypes: getBaseTypes,
            getReturnTypeOfSignature: getReturnTypeOfSignature,
            getNonNullableType: getNonNullableType,
            getSymbolsInScope: getSymbolsInScope,
            getSymbolAtLocation: getSymbolAtLocation,
            getShorthandAssignmentValueSymbol: getShorthandAssignmentValueSymbol,
            getExportSpecifierLocalTargetSymbol: getExportSpecifierLocalTargetSymbol,
            getTypeAtLocation: getTypeOfNode,
            getPropertySymbolOfDestructuringAssignment: getPropertySymbolOfDestructuringAssignment,
            typeToString: typeToString,
            getSymbolDisplayBuilder: getSymbolDisplayBuilder,
            symbolToString: symbolToString,
            getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
            getRootSymbols: getRootSymbols,
            getContextualType: getContextualType,
            getFullyQualifiedName: getFullyQualifiedName,
            getResolvedSignature: getResolvedSignature,
            getConstantValue: getConstantValue,
            isValidPropertyAccess: isValidPropertyAccess,
            getSignatureFromDeclaration: getSignatureFromDeclaration,
            isImplementationOfOverload: isImplementationOfOverload,
            getAliasedSymbol: resolveAlias,
            getEmitResolver: getEmitResolver,
            getExportsOfModule: getExportsOfModuleAsArray,
            getJsxElementAttributesType: getJsxElementAttributesType,
            getJsxIntrinsicTagNames: getJsxIntrinsicTagNames,
            isOptionalParameter: isOptionalParameter
        };
        var unknownSymbol = createSymbol(4 /* Property */ | 67108864 /* Transient */, "unknown");
        var resolvingSymbol = createSymbol(67108864 /* Transient */, "__resolving__");
        var anyType = createIntrinsicType(1 /* Any */, "any");
        var stringType = createIntrinsicType(2 /* String */, "string");
        var numberType = createIntrinsicType(4 /* Number */, "number");
        var booleanType = createIntrinsicType(8 /* Boolean */, "boolean");
        var esSymbolType = createIntrinsicType(16777216 /* ESSymbol */, "symbol");
        var voidType = createIntrinsicType(16 /* Void */, "void");
        var undefinedType = createIntrinsicType(32 /* Undefined */, "undefined");
        var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(32 /* Undefined */ | 2097152 /* ContainsWideningType */, "undefined");
        var nullType = createIntrinsicType(64 /* Null */, "null");
        var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(64 /* Null */ | 2097152 /* ContainsWideningType */, "null");
        var unknownType = createIntrinsicType(1 /* Any */, "unknown");
        var neverType = createIntrinsicType(134217728 /* Never */, "never");
        var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
        var emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
        emptyGenericType.instantiations = {};
        var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, 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, emptyArray, emptyArray, undefined, undefined);
        var anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
        var unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
        var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
        var globals = {};
        /**
         * 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 getGlobalESSymbolConstructorSymbol;
        var getGlobalPromiseConstructorSymbol;
        var globalObjectType;
        var globalFunctionType;
        var globalArrayType;
        var globalReadonlyArrayType;
        var globalStringType;
        var globalNumberType;
        var globalBooleanType;
        var globalRegExpType;
        var anyArrayType;
        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 getGlobalTemplateStringsArrayType;
        var getGlobalESSymbolType;
        var getGlobalIterableType;
        var getGlobalIteratorType;
        var getGlobalIterableIteratorType;
        var getGlobalClassDecoratorType;
        var getGlobalParameterDecoratorType;
        var getGlobalPropertyDecoratorType;
        var getGlobalMethodDecoratorType;
        var getGlobalTypedPropertyDescriptorType;
        var getGlobalPromiseType;
        var tryGetGlobalPromiseType;
        var getGlobalPromiseLikeType;
        var getInstantiatedGlobalPromiseLikeType;
        var getGlobalPromiseConstructorLikeType;
        var getGlobalThenableType;
        var jsxElementClassType;
        var deferredNodes;
        var deferredUnusedIdentifierNodes;
        var flowLoopStart = 0;
        var flowLoopCount = 0;
        var visitedFlowCount = 0;
        var tupleTypes = {};
        var unionTypes = {};
        var intersectionTypes = {};
        var stringLiteralTypes = {};
        var resolutionTargets = [];
        var resolutionResults = [];
        var resolutionPropertyNames = [];
        var mergedSymbols = [];
        var symbolLinks = [];
        var nodeLinks = [];
        var flowLoopCaches = [];
        var flowLoopNodes = [];
        var flowLoopKeys = [];
        var flowLoopTypes = [];
        var visitedFlowNodes = [];
        var visitedFlowTypes = [];
        var potentialThisCollisions = [];
        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["All"] = 4194303] = "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["StringStrictFacts"] = 4079361] = "StringStrictFacts";
            TypeFacts[TypeFacts["StringFacts"] = 4194049] = "StringFacts";
            TypeFacts[TypeFacts["NumberStrictFacts"] = 4079234] = "NumberStrictFacts";
            TypeFacts[TypeFacts["NumberFacts"] = 4193922] = "NumberFacts";
            TypeFacts[TypeFacts["BooleanStrictFacts"] = 4078980] = "BooleanStrictFacts";
            TypeFacts[TypeFacts["BooleanFacts"] = 4193668] = "BooleanFacts";
            TypeFacts[TypeFacts["SymbolStrictFacts"] = 1981320] = "SymbolStrictFacts";
            TypeFacts[TypeFacts["SymbolFacts"] = 4193160] = "SymbolFacts";
            TypeFacts[TypeFacts["ObjectStrictFacts"] = 1972176] = "ObjectStrictFacts";
            TypeFacts[TypeFacts["ObjectFacts"] = 4184016] = "ObjectFacts";
            TypeFacts[TypeFacts["FunctionStrictFacts"] = 1970144] = "FunctionStrictFacts";
            TypeFacts[TypeFacts["FunctionFacts"] = 4181984] = "FunctionFacts";
            TypeFacts[TypeFacts["UndefinedFacts"] = 2457472] = "UndefinedFacts";
            TypeFacts[TypeFacts["NullFacts"] = 2340752] = "NullFacts";
        })(TypeFacts || (TypeFacts = {}));
        var typeofEQFacts = {
            "string": 1 /* TypeofEQString */,
            "number": 2 /* TypeofEQNumber */,
            "boolean": 4 /* TypeofEQBoolean */,
            "symbol": 8 /* TypeofEQSymbol */,
            "undefined": 16384 /* EQUndefined */,
            "object": 16 /* TypeofEQObject */,
            "function": 32 /* TypeofEQFunction */
        };
        var typeofNEFacts = {
            "string": 128 /* TypeofNEString */,
            "number": 256 /* TypeofNENumber */,
            "boolean": 512 /* TypeofNEBoolean */,
            "symbol": 1024 /* TypeofNESymbol */,
            "undefined": 131072 /* NEUndefined */,
            "object": 2048 /* TypeofNEObject */,
            "function": 4096 /* TypeofNEFunction */
        };
        var typeofTypesByName = {
            "string": stringType,
            "number": numberType,
            "boolean": booleanType,
            "symbol": esSymbolType,
            "undefined": undefinedType
        };
        var jsxElementType;
        /** Things we lazy load from the JSX namespace */
        var jsxTypes = {};
        var JsxNames = {
            JSX: "JSX",
            IntrinsicElements: "IntrinsicElements",
            ElementClass: "ElementClass",
            ElementAttributesPropertyNameContainer: "ElementAttributesProperty",
            Element: "Element",
            IntrinsicAttributes: "IntrinsicAttributes",
            IntrinsicClassAttributes: "IntrinsicClassAttributes"
        };
        var subtypeRelation = {};
        var assignableRelation = {};
        var comparableRelation = {};
        var identityRelation = {};
        // 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 builtinGlobals = (_a = {},
            _a[undefinedSymbol.name] = undefinedSymbol,
            _a
        );
        initializeTypeChecker();
        return checker;
        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++;
            return new Symbol(flags, name);
        }
        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 |= 107455 /* EnumMemberExcludes */;
            if (flags & 16 /* Function */)
                result |= 106927 /* FunctionExcludes */;
            if (flags & 32 /* Class */)
                result |= 899519 /* ClassExcludes */;
            if (flags & 64 /* Interface */)
                result |= 792960 /* 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 |= 530912 /* TypeParameterExcludes */;
            if (flags & 524288 /* TypeAlias */)
                result |= 793056 /* TypeAliasExcludes */;
            if (flags & 8388608 /* Alias */)
                result |= 8388608 /* 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 | 33554432 /* Merged */, symbol.name);
            result.declarations = symbol.declarations.slice(0);
            result.parent = symbol.parent;
            if (symbol.valueDeclaration)
                result.valueDeclaration = symbol.valueDeclaration;
            if (symbol.constEnumOnlyModule)
                result.constEnumOnlyModule = true;
            if (symbol.members)
                result.members = cloneSymbolTable(symbol.members);
            if (symbol.exports)
                result.exports = cloneSymbolTable(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 === 225 /* ModuleDeclaration */ && source.valueDeclaration.kind !== 225 /* ModuleDeclaration */))) {
                    // other kinds of value declarations take precedence over modules
                    target.valueDeclaration = source.valueDeclaration;
                }
                ts.forEach(source.declarations, function (node) {
                    target.declarations.push(node);
                });
                if (source.members) {
                    if (!target.members)
                        target.members = {};
                    mergeSymbolTable(target.members, source.members);
                }
                if (source.exports) {
                    if (!target.exports)
                        target.exports = {};
                    mergeSymbolTable(target.exports, source.exports);
                }
                recordMergedSymbol(target, source);
            }
            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(node.name ? node.name : node, message_2, symbolToString(source));
                });
                ts.forEach(target.declarations, function (node) {
                    error(node.name ? node.name : node, message_2, symbolToString(source));
                });
            }
        }
        function cloneSymbolTable(symbolTable) {
            var result = {};
            for (var id in symbolTable) {
                if (ts.hasProperty(symbolTable, id)) {
                    result[id] = symbolTable[id];
                }
            }
            return result;
        }
        function mergeSymbolTable(target, source) {
            for (var id in source) {
                if (ts.hasProperty(source, id)) {
                    if (!ts.hasProperty(target, id)) {
                        target[id] = source[id];
                    }
                    else {
                        var symbol = target[id];
                        if (!(symbol.flags & 33554432 /* Merged */)) {
                            target[id] = symbol = cloneSymbol(symbol);
                        }
                        mergeSymbol(symbol, source[id]);
                    }
                }
            }
        }
        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);
                if (!mainModule) {
                    return;
                }
                // obtain item referenced by 'export='
                mainModule = resolveExternalModuleSymbol(mainModule);
                if (mainModule.flags & 1536 /* Namespace */) {
                    // if module symbol has already been merged - it is safe to use it.
                    // otherwise clone it
                    mainModule = mainModule.flags & 33554432 /* Merged */ ? mainModule : cloneSymbol(mainModule);
                    mergeSymbol(mainModule, moduleAugmentation.symbol);
                }
                else {
                    error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
                }
            }
        }
        function addToSymbolTable(target, source, message) {
            for (var id in source) {
                if (ts.hasProperty(source, id)) {
                    if (ts.hasProperty(target, id)) {
                        // Error on redeclarations
                        ts.forEach(target[id].declarations, addDeclarationDiagnostic(id, message));
                    }
                    else {
                        target[id] = source[id];
                    }
                }
            }
            function addDeclarationDiagnostic(id, message) {
                return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); };
            }
        }
        function getSymbolLinks(symbol) {
            if (symbol.flags & 67108864 /* Transient */)
                return symbol;
            var id = getSymbolId(symbol);
            return symbolLinks[id] || (symbolLinks[id] = {});
        }
        function getNodeLinks(node) {
            var nodeId = getNodeId(node);
            return nodeLinks[nodeId] || (nodeLinks[nodeId] = {});
        }
        function isGlobalSourceFile(node) {
            return node.kind === 256 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
        }
        function getSymbol(symbols, name, meaning) {
            if (meaning && ts.hasProperty(symbols, name)) {
                var symbol = symbols[name];
                ts.Debug.assert((symbol.flags & 16777216 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                if (symbol.flags & meaning) {
                    return symbol;
                }
                if (symbol.flags & 8388608 /* 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)) {
                    // nodes are in different files and order cannot be determines
                    return true;
                }
                var sourceFiles = host.getSourceFiles();
                return ts.indexOf(sourceFiles, declarationFile) <= ts.indexOf(sourceFiles, useFile);
            }
            if (declaration.pos <= usage.pos) {
                // declaration is before usage
                // still might be illegal if usage is in the initializer of the variable declaration
                return declaration.kind !== 218 /* VariableDeclaration */ ||
                    !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage);
            }
            // declaration is after usage
            // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
            return isUsedInFunctionOrNonStaticProperty(declaration, usage);
            function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
                var container = ts.getEnclosingBlockScopeContainer(declaration);
                switch (declaration.parent.parent.kind) {
                    case 200 /* VariableStatement */:
                    case 206 /* ForStatement */:
                    case 208 /* 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;
                }
                switch (declaration.parent.parent.kind) {
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                        // ForIn/ForOf case - use site should not be used in expression part
                        if (isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container)) {
                            return true;
                        }
                }
                return false;
            }
            function isUsedInFunctionOrNonStaticProperty(declaration, usage) {
                var container = ts.getEnclosingBlockScopeContainer(declaration);
                var current = usage;
                while (current) {
                    if (current === container) {
                        return false;
                    }
                    if (ts.isFunctionLike(current)) {
                        return true;
                    }
                    var initializerOfNonStaticProperty = current.parent &&
                        current.parent.kind === 145 /* PropertyDeclaration */ &&
                        (current.parent.flags & 32 /* Static */) === 0 &&
                        current.parent.initializer === current;
                    if (initializerOfNonStaticProperty) {
                        return true;
                    }
                    current = current.parent;
                }
                return false;
            }
        }
        // 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.
        function resolveName(location, name, meaning, nameNotFoundMessage, nameArg) {
            var result;
            var lastLocation;
            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 = getSymbol(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 & 793056 /* Type */ && lastLocation.kind !== 273 /* JSDocComment */) {
                                useResult = result.flags & 262144 /* TypeParameter */
                                    ? lastLocation === location.type ||
                                        lastLocation.kind === 142 /* Parameter */ ||
                                        lastLocation.kind === 141 /* TypeParameter */
                                    : 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 === 142 /* Parameter */ ||
                                        (lastLocation === location.type &&
                                            result.valueDeclaration.kind === 142 /* Parameter */);
                            }
                        }
                        if (useResult) {
                            break loop;
                        }
                        else {
                            result = undefined;
                        }
                    }
                }
                switch (location.kind) {
                    case 256 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location))
                            break;
                        isInExternalModule = true;
                    case 225 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports;
                        if (location.kind === 256 /* 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["default"]) {
                                var localSymbol = ts.getLocalSymbolForExportDefault(result);
                                if (localSymbol && (result.flags & meaning) && localSymbol.name === 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.
                            if (ts.hasProperty(moduleExports, name) &&
                                moduleExports[name].flags === 8388608 /* Alias */ &&
                                ts.getDeclarationOfKind(moduleExports[name], 238 /* ExportSpecifier */)) {
                                break;
                            }
                        }
                        if (result = getSymbol(moduleExports, name, meaning & 8914931 /* ModuleMember */)) {
                            break loop;
                        }
                        break;
                    case 224 /* EnumDeclaration */:
                        if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 145 /* PropertyDeclaration */:
                    case 144 /* 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) && !(location.flags & 32 /* Static */)) {
                            var ctor = findConstructorDeclaration(location.parent);
                            if (ctor && ctor.locals) {
                                if (getSymbol(ctor.locals, name, meaning & 107455 /* Value */)) {
                                    // Remember the property node, it will be used later to report appropriate error
                                    propertyWithInvalidInitializer = location;
                                }
                            }
                        }
                        break;
                    case 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 222 /* InterfaceDeclaration */:
                        if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & 793056 /* Type */)) {
                            if (lastLocation && lastLocation.flags & 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 === 192 /* ClassExpression */ && meaning & 32 /* Class */) {
                            var className = location.name;
                            if (className && name === className.text) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        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 140 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 222 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & 793056 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 148 /* Constructor */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 220 /* FunctionDeclaration */:
                    case 180 /* ArrowFunction */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 179 /* FunctionExpression */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        if (meaning & 16 /* Function */) {
                            var functionName = location.name;
                            if (functionName && name === functionName.text) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 143 /* 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 === 142 /* 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;
                }
                lastLocation = location;
                location = location.parent;
            }
            if (result && nameNotFoundMessage && noUnusedIdentifiers) {
                result.isReferenced = true;
            }
            if (!result) {
                result = getSymbol(globals, name, meaning);
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
                        !checkAndReportErrorForExtendingInterface(errorLocation)) {
                        error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                    }
                }
                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), typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                    return undefined;
                }
                // Only check for block-scoped variable if we 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 meaning
                // block - scope 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 (meaning & 2 /* BlockScopedVariable */) {
                    var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
                    if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */) {
                        checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
                    }
                }
                // If we're in an external module, we can't reference symbols created from UMD export declarations
                if (result && isInExternalModule) {
                    var decls = result.declarations;
                    if (decls && decls.length === 1 && decls[0].kind === 228 /* NamespaceExportDeclaration */) {
                        error(errorLocation, ts.Diagnostics.Identifier_0_must_be_imported_from_a_module, name);
                    }
                }
            }
            return result;
        }
        function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) {
            if (!errorLocation || (errorLocation.kind === 69 /* 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, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(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 && !(location.flags & 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, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                            return true;
                        }
                    }
                }
                location = location.parent;
            }
            return false;
        }
        function checkAndReportErrorForExtendingInterface(errorLocation) {
            var parentClassExpression = errorLocation;
            while (parentClassExpression) {
                var kind = parentClassExpression.kind;
                if (kind === 69 /* Identifier */ || kind === 172 /* PropertyAccessExpression */) {
                    parentClassExpression = parentClassExpression.parent;
                    continue;
                }
                if (kind === 194 /* ExpressionWithTypeArguments */) {
                    break;
                }
                return false;
            }
            if (!parentClassExpression) {
                return false;
            }
            var expression = parentClassExpression.expression;
            if (resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)) {
                error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression));
                return true;
            }
            return false;
        }
        function checkResolvedBlockScopedVariable(result, errorLocation) {
            ts.Debug.assert((result.flags & 2 /* BlockScopedVariable */) !== 0);
            // Block-scoped variables cannot be used before their definition
            var declaration = ts.forEach(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) ? d : undefined; });
            ts.Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
            if (!isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 218 /* VariableDeclaration */), errorLocation)) {
                error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.declarationNameToString(declaration.name));
            }
        }
        /* 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) {
            if (!parent) {
                return false;
            }
            for (var current = initial; current && current !== stopAt && !ts.isFunctionLike(current); current = current.parent) {
                if (current === parent) {
                    return true;
                }
            }
            return false;
        }
        function getAnyImportSyntax(node) {
            if (ts.isAliasSymbolDeclaration(node)) {
                if (node.kind === 229 /* ImportEqualsDeclaration */) {
                    return node;
                }
                while (node && node.kind !== 230 /* ImportDeclaration */) {
                    node = node.parent;
                }
                return node;
            }
        }
        function getDeclarationOfAliasSymbol(symbol) {
            return ts.forEach(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; });
        }
        function getTargetOfImportEqualsDeclaration(node) {
            if (node.moduleReference.kind === 240 /* ExternalModuleReference */) {
                return resolveExternalModuleSymbol(resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node)));
            }
            return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, node);
        }
        function getTargetOfImportClause(node) {
            var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
            if (moduleSymbol) {
                var exportDefaultSymbol = ts.isShorthandAmbientModule(moduleSymbol.valueDeclaration) ?
                    moduleSymbol :
                    moduleSymbol.exports["export="] ?
                        getPropertyOfType(getTypeOfSymbol(moduleSymbol.exports["export="]), "default") :
                        resolveSymbol(moduleSymbol.exports["default"]);
                if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
                    error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
                }
                else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
                    return resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
                }
                return exportDefaultSymbol;
            }
        }
        function getTargetOfNamespaceImport(node) {
            var moduleSpecifier = node.parent.parent.moduleSpecifier;
            return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier);
        }
        // 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.flags & (793056 /* Type */ | 1536 /* Namespace */)) {
                return valueSymbol;
            }
            var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.name);
            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) {
            if (symbol.flags & 1536 /* Module */) {
                var exports = getExportsOfSymbol(symbol);
                if (ts.hasProperty(exports, name)) {
                    return resolveSymbol(exports[name]);
                }
            }
        }
        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) {
            var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
            var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier);
            if (targetSymbol) {
                var name_10 = specifier.propertyName || specifier.name;
                if (name_10.text) {
                    if (ts.isShorthandAmbientModule(moduleSymbol.valueDeclaration)) {
                        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["export="]) {
                        symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name_10.text);
                    }
                    else {
                        symbolFromVariable = getPropertyOfVariable(targetSymbol, name_10.text);
                    }
                    // if symbolFromVariable is export - get its final target
                    symbolFromVariable = resolveSymbol(symbolFromVariable);
                    var symbolFromModule = getExportOfModule(targetSymbol, name_10.text);
                    var symbol = symbolFromModule && symbolFromVariable ?
                        combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
                        symbolFromModule || symbolFromVariable;
                    if (!symbol) {
                        error(name_10, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_10));
                    }
                    return symbol;
                }
            }
        }
        function getTargetOfImportSpecifier(node) {
            return getExternalModuleMember(node.parent.parent.parent, node);
        }
        function getTargetOfNamespaceExportDeclaration(node) {
            return resolveExternalModuleSymbol(node.parent.symbol);
        }
        function getTargetOfExportSpecifier(node) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node) :
                resolveEntityName(node.propertyName || node.name, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */);
        }
        function getTargetOfExportAssignment(node) {
            return resolveEntityName(node.expression, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */);
        }
        function getTargetOfAliasDeclaration(node) {
            switch (node.kind) {
                case 229 /* ImportEqualsDeclaration */:
                    return getTargetOfImportEqualsDeclaration(node);
                case 231 /* ImportClause */:
                    return getTargetOfImportClause(node);
                case 232 /* NamespaceImport */:
                    return getTargetOfNamespaceImport(node);
                case 234 /* ImportSpecifier */:
                    return getTargetOfImportSpecifier(node);
                case 238 /* ExportSpecifier */:
                    return getTargetOfExportSpecifier(node);
                case 235 /* ExportAssignment */:
                    return getTargetOfExportAssignment(node);
                case 228 /* NamespaceExportDeclaration */:
                    return getTargetOfNamespaceExportDeclaration(node);
            }
        }
        function resolveSymbol(symbol) {
            return symbol && symbol.flags & 8388608 /* Alias */ && !(symbol.flags & (107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */)) ? resolveAlias(symbol) : symbol;
        }
        function resolveAlias(symbol) {
            ts.Debug.assert((symbol.flags & 8388608 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.target) {
                links.target = resolvingSymbol;
                var node = getDeclarationOfAliasSymbol(symbol);
                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);
                if (node.kind === 235 /* ExportAssignment */) {
                    // export default <symbol>
                    checkExpressionCached(node.expression);
                }
                else if (node.kind === 238 /* 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, importDeclaration, 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 === 69 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            // Check for case 1 and 3 in the above example
            if (entityName.kind === 69 /* Identifier */ || entityName.parent.kind === 139 /* QualifiedName */) {
                return resolveEntityName(entityName, 1536 /* 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 === 229 /* ImportEqualsDeclaration */);
                return resolveEntityName(entityName, 107455 /* Value */ | 793056 /* Type */ | 1536 /* 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) {
            if (ts.nodeIsMissing(name)) {
                return undefined;
            }
            var symbol;
            if (name.kind === 69 /* Identifier */) {
                var message = meaning === 1536 /* Namespace */ ? ts.Diagnostics.Cannot_find_namespace_0 : ts.Diagnostics.Cannot_find_name_0;
                symbol = resolveName(name, name.text, meaning, ignoreErrors ? undefined : message, name);
                if (!symbol) {
                    return undefined;
                }
            }
            else if (name.kind === 139 /* QualifiedName */ || name.kind === 172 /* PropertyAccessExpression */) {
                var left = name.kind === 139 /* QualifiedName */ ? name.left : name.expression;
                var right = name.kind === 139 /* QualifiedName */ ? name.right : name.name;
                var namespace = resolveEntityName(left, 1536 /* Namespace */, ignoreErrors);
                if (!namespace || ts.nodeIsMissing(right)) {
                    return undefined;
                }
                else if (namespace === unknownSymbol) {
                    return namespace;
                }
                symbol = getSymbol(getExportsOfSymbol(namespace), right.text, meaning);
                if (!symbol) {
                    if (!ignoreErrors) {
                        error(right, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
                    }
                    return undefined;
                }
            }
            else {
                ts.Debug.fail("Unknown entity name kind.");
            }
            ts.Debug.assert((symbol.flags & 16777216 /* 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) {
            if (moduleReferenceExpression.kind !== 9 /* StringLiteral */) {
                return;
            }
            var moduleReferenceLiteral = moduleReferenceExpression;
            // Module names are escaped in our symbol table.  However, string literal values aren't.
            // Escape the name in the "require(...)" clause to ensure we find the right symbol.
            var moduleName = ts.escapeIdentifier(moduleReferenceLiteral.text);
            if (moduleName === undefined) {
                return;
            }
            var isRelative = ts.isExternalModuleNameRelative(moduleName);
            if (!isRelative) {
                var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
                if (symbol) {
                    // merged symbol is module declaration symbol combined with all augmentations
                    return getMergedSymbol(symbol);
                }
            }
            var resolvedModule = ts.getResolvedModule(ts.getSourceFileOfNode(location), moduleReferenceLiteral.text);
            var sourceFile = resolvedModule && 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(moduleReferenceLiteral, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
                }
                return undefined;
            }
            if (patternAmbientModules) {
                var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleName);
                if (pattern) {
                    return getMergedSymbol(pattern.symbol);
                }
            }
            if (moduleNotFoundError) {
                // report errors only if it was requested
                error(moduleReferenceLiteral, moduleNotFoundError, moduleName);
            }
            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) {
            return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports["export="])) || 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) {
            var symbol = resolveExternalModuleSymbol(moduleSymbol);
            if (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));
                symbol = undefined;
            }
            return symbol;
        }
        function hasExportAssignmentSymbol(moduleSymbol) {
            return moduleSymbol.exports["export="] !== undefined;
        }
        function getExportsOfModuleAsArray(moduleSymbol) {
            return symbolsToArray(getExportsOfModule(moduleSymbol));
        }
        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 = getExportsForModule(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) {
            for (var id in source) {
                if (id !== "default" && !ts.hasProperty(target, id)) {
                    target[id] = source[id];
                    if (lookupTable && exportNode) {
                        lookupTable[id] = {
                            specifierText: ts.getTextOfNode(exportNode.moduleSpecifier)
                        };
                    }
                }
                else if (lookupTable && exportNode && id !== "default" && ts.hasProperty(target, id) && resolveSymbol(target[id]) !== resolveSymbol(source[id])) {
                    if (!lookupTable[id].exportsWithDuplicate) {
                        lookupTable[id].exportsWithDuplicate = [exportNode];
                    }
                    else {
                        lookupTable[id].exportsWithDuplicate.push(exportNode);
                    }
                }
            }
        }
        function getExportsForModule(moduleSymbol) {
            var visitedSymbols = [];
            return visit(moduleSymbol) || moduleSymbol.exports;
            // 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.contains(visitedSymbols, symbol))) {
                    return;
                }
                visitedSymbols.push(symbol);
                var symbols = cloneSymbolTable(symbol.exports);
                // All export * declarations are collected in an __export symbol by the binder
                var exportStars = symbol.exports["__export"];
                if (exportStars) {
                    var nestedSymbols = {};
                    var lookupTable = {};
                    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, node);
                    }
                    for (var id in lookupTable) {
                        var exportsWithDuplicate = lookupTable[id].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) || ts.hasProperty(symbols, id)) {
                            continue;
                        }
                        for (var _b = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _b < exportsWithDuplicate_1.length; _b++) {
                            var node = exportsWithDuplicate_1[_b];
                            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[id].specifierText, 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) {
            // If it is an instantiated symbol, then it is a value if the symbol it is an
            // instantiation of is a value.
            if (symbol.flags & 16777216 /* Instantiated */) {
                return symbolIsValue(getSymbolLinks(symbol).target);
            }
            // If the symbol has the value flag, it is trivially a value.
            if (symbol.flags & 107455 /* Value */) {
                return true;
            }
            // If it is an alias, then it is a value if the symbol it resolves to is a value.
            if (symbol.flags & 8388608 /* Alias */) {
                return (resolveAlias(symbol).flags & 107455 /* Value */) !== 0;
            }
            return false;
        }
        function findConstructorDeclaration(node) {
            var members = node.members;
            for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
                var member = members_1[_i];
                if (member.kind === 148 /* Constructor */ && ts.nodeIsPresent(member.body)) {
                    return member;
                }
            }
        }
        function createType(flags) {
            var result = new Type(checker, flags);
            result.id = typeCount;
            typeCount++;
            return result;
        }
        function createIntrinsicType(kind, intrinsicName) {
            var type = createType(kind);
            type.intrinsicName = intrinsicName;
            return type;
        }
        function createObjectType(kind, symbol) {
            var type = createType(kind);
            type.symbol = symbol;
            return type;
        }
        // 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;
            for (var id in members) {
                if (ts.hasProperty(members, id)) {
                    if (!isReservedMemberName(id)) {
                        if (!result)
                            result = [];
                        var symbol = members[id];
                        if (symbolIsValue(symbol)) {
                            result.push(symbol);
                        }
                    }
                }
            }
            return result || emptyArray;
        }
        function setObjectTypeMembers(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 setObjectTypeMembers(createObjectType(65536 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function forEachSymbolTableInScope(enclosingDeclaration, callback) {
            var result;
            for (var location_1 = enclosingDeclaration; location_1; location_1 = location_1.parent) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location_1.locals && !isGlobalSourceFile(location_1)) {
                    if (result = callback(location_1.locals)) {
                        return result;
                    }
                }
                switch (location_1.kind) {
                    case 256 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location_1)) {
                            break;
                        }
                    case 225 /* ModuleDeclaration */:
                        if (result = callback(getSymbolOfNode(location_1).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 */ : 1536 /* Namespace */;
        }
        function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing) {
            function getAccessibleSymbolChainFromSymbolTable(symbols) {
                function canQualifySymbol(symbolFromSymbolTable, meaning) {
                    // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
                    if (!needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning)) {
                        return true;
                    }
                    // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
                    var accessibleParent = getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
                    return !!accessibleParent;
                }
                function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol) {
                    if (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
                        return !ts.forEach(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
                            canQualifySymbol(symbolFromSymbolTable, meaning);
                    }
                }
                // If symbol is directly available by its name in the symbol table
                if (isAccessible(ts.lookUp(symbols, symbol.name))) {
                    return [symbol];
                }
                // Check if symbol is any of the alias
                return ts.forEachValue(symbols, function (symbolFromSymbolTable) {
                    if (symbolFromSymbolTable.flags & 8388608 /* Alias */
                        && symbolFromSymbolTable.name !== "export="
                        && !ts.getDeclarationOfKind(symbolFromSymbolTable, 238 /* ExportSpecifier */)) {
                        if (!useOnlyExternalAliasing ||
                            // Is this external alias, then use it to name
                            ts.forEach(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration)) {
                            var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
                            if (isAccessible(symbolFromSymbolTable, resolveAlias(symbolFromSymbolTable))) {
                                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);
                            }
                        }
                    }
                });
            }
            if (symbol) {
                if (!(isPropertyOrMethodDeclarationSymbol(symbol))) {
                    return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
                }
            }
        }
        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
                if (!ts.hasProperty(symbolTable, symbol.name)) {
                    // Continue to the next symbol table
                    return false;
                }
                // If the symbol with this name is present it should refer to the symbol
                var symbolFromSymbolTable = symbolTable[symbol.name];
                if (symbolFromSymbolTable === symbol) {
                    // No need to qualify
                    return true;
                }
                // Qualify if the symbol from symbol table has same meaning as expected
                symbolFromSymbolTable = (symbolFromSymbolTable.flags & 8388608 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 238 /* 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 145 /* PropertyDeclaration */:
                        case 147 /* MethodDeclaration */:
                        case 149 /* GetAccessor */:
                        case 150 /* SetAccessor */:
                            continue;
                        default:
                            return false;
                    }
                }
                return true;
            }
            return false;
        }
        function isSymbolAccessible(symbol, enclosingDeclaration, meaning) {
            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]);
                        if (!hasAccessibleDeclarations) {
                            return {
                                accessibility: 1 /* NotAccessible */,
                                errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                                errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, 1536 /* 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) {
                for (; declaration; declaration = declaration.parent) {
                    if (hasExternalModuleSymbol(declaration)) {
                        return getSymbolOfNode(declaration);
                    }
                }
            }
        }
        function hasExternalModuleSymbol(declaration) {
            return ts.isAmbientModule(declaration) || (declaration.kind === 256 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasVisibleDeclarations(symbol) {
            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 &&
                        !(anyImportSyntax.flags & 1 /* Export */) &&
                        isDeclarationVisible(anyImportSyntax.parent)) {
                        getNodeLinks(declaration).isVisible = true;
                        if (aliasesToMakeVisible) {
                            if (!ts.contains(aliasesToMakeVisible, anyImportSyntax)) {
                                aliasesToMakeVisible.push(anyImportSyntax);
                            }
                        }
                        else {
                            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 === 158 /* TypeQuery */ || ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
                // Typeof value
                meaning = 107455 /* Value */ | 1048576 /* ExportValue */;
            }
            else if (entityName.kind === 139 /* QualifiedName */ || entityName.kind === 172 /* PropertyAccessExpression */ ||
                entityName.parent.kind === 229 /* ImportEqualsDeclaration */) {
                // Left identifier from type reference or TypeAlias
                // Entity name of the import declaration
                meaning = 1536 /* Namespace */;
            }
            else {
                // Type Reference or TypeAlias entity = Identifier
                meaning = 793056 /* Type */;
            }
            var firstIdentifier = getFirstIdentifier(entityName);
            var symbol = resolveName(enclosingDeclaration, firstIdentifier.text, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
            // Verify if the symbol is accessible
            return (symbol && hasVisibleDeclarations(symbol)) || {
                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) {
            var writer = ts.getSingleLineStringWriter();
            getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
            var result = writer.string();
            ts.releaseStringWriter(writer);
            return result;
        }
        function signatureToString(signature, enclosingDeclaration, flags, kind) {
            var writer = ts.getSingleLineStringWriter();
            getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind);
            var result = writer.string();
            ts.releaseStringWriter(writer);
            return result;
        }
        function typeToString(type, enclosingDeclaration, flags) {
            var writer = ts.getSingleLineStringWriter();
            getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
            var result = writer.string();
            ts.releaseStringWriter(writer);
            var maxLength = compilerOptions.noErrorTruncation || flags & 4 /* NoTruncation */ ? undefined : 100;
            if (maxLength && result.length >= maxLength) {
                result = result.substr(0, maxLength - "...".length) + "...";
            }
            return result;
        }
        function typePredicateToString(typePredicate, enclosingDeclaration, flags) {
            var writer = ts.getSingleLineStringWriter();
            getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags);
            var result = writer.string();
            ts.releaseStringWriter(writer);
            return result;
        }
        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 = type.symbol.declarations[0].parent;
                while (node.kind === 164 /* ParenthesizedType */) {
                    node = node.parent;
                }
                if (node.kind === 223 /* TypeAliasDeclaration */) {
                    return getSymbolOfNode(node);
                }
            }
            return undefined;
        }
        function isTopLevelInExternalModuleAugmentation(node) {
            return node && node.parent &&
                node.parent.kind === 226 /* ModuleBlock */ &&
                ts.isExternalModuleAugmentation(node.parent.parent);
        }
        function getSymbolDisplayBuilder() {
            function getNameOfSymbol(symbol) {
                if (symbol.declarations && symbol.declarations.length) {
                    var declaration = symbol.declarations[0];
                    if (declaration.name) {
                        return ts.declarationNameToString(declaration.name);
                    }
                    switch (declaration.kind) {
                        case 192 /* ClassExpression */:
                            return "(Anonymous class)";
                        case 179 /* FunctionExpression */:
                        case 180 /* ArrowFunction */:
                            return "(Anonymous function)";
                    }
                }
                return symbol.name;
            }
            /**
             * 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, 19 /* OpenBracketToken */);
                    if (ts.isSingleOrDoubleQuote(firstChar)) {
                        writer.writeStringLiteral(symbolName);
                    }
                    else {
                        writer.writeSymbol(symbolName, symbol);
                    }
                    writePunctuation(writer, 20 /* CloseBracketToken */);
                }
                else {
                    writePunctuation(writer, 21 /* 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 (symbol.flags & 16777216 /* Instantiated */) {
                                buildDisplayForTypeArgumentsAndDelimiters(getTypeParametersOfClassOrInterface(parentSymbol), symbol.mapper, writer, enclosingDeclaration);
                            }
                            else {
                                buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration);
                            }
                        }
                        appendPropertyOrElementAccessForSymbol(symbol, writer);
                    }
                    else {
                        appendSymbolNameOnly(symbol, writer);
                    }
                    parentSymbol = symbol;
                }
                // const 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);
                function walkSymbol(symbol, meaning) {
                    if (symbol) {
                        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.
                            walkSymbol(getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol), getQualifiedLeftMeaning(meaning));
                        }
                        if (accessibleSymbolChain) {
                            for (var _i = 0, accessibleSymbolChain_1 = accessibleSymbolChain; _i < accessibleSymbolChain_1.length; _i++) {
                                var accessibleSymbol = accessibleSymbolChain_1[_i];
                                appendParentTypeArgumentsAndSymbolName(accessibleSymbol);
                            }
                        }
                        else {
                            // If we didn't find accessible symbol chain for this symbol, break if this is external module
                            if (!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) {
                                return;
                            }
                            // if this is anonymous type break
                            if (symbol.flags & 2048 /* TypeLiteral */ || symbol.flags & 4096 /* ObjectLiteral */) {
                                return;
                            }
                            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 = 128 /* UseFullyQualifiedType */ & typeFlags;
                if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) {
                    walkSymbol(symbol, meaning);
                    return;
                }
                return appendParentTypeArgumentsAndSymbolName(symbol);
            }
            function buildTypeDisplay(type, writer, enclosingDeclaration, globalFlags, symbolStack) {
                var globalFlagsToPass = globalFlags & 16 /* WriteOwnNameForAnyLike */;
                var inObjectTypeLiteral = false;
                return writeType(type, globalFlags);
                function writeType(type, flags) {
                    // Write undefined/null type as any
                    if (type.flags & 150995071 /* Intrinsic */) {
                        // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving
                        writer.writeKeyword(!(globalFlags & 16 /* WriteOwnNameForAnyLike */) && isTypeAny(type)
                            ? "any"
                            : type.intrinsicName);
                    }
                    else if (type.flags & 33554432 /* ThisType */) {
                        if (inObjectTypeLiteral) {
                            writer.reportInaccessibleThisError();
                        }
                        writer.writeKeyword("this");
                    }
                    else if (type.flags & 4096 /* Reference */) {
                        writeTypeReference(type, flags);
                    }
                    else if (type.flags & (1024 /* Class */ | 2048 /* Interface */ | 128 /* Enum */ | 512 /* TypeParameter */)) {
                        // The specified symbol flags need to be reinterpreted as type flags
                        buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793056 /* Type */, 0 /* None */, flags);
                    }
                    else if (type.flags & 8192 /* Tuple */) {
                        writeTupleType(type);
                    }
                    else if (type.flags & 49152 /* UnionOrIntersection */) {
                        writeUnionOrIntersectionType(type, flags);
                    }
                    else if (type.flags & 65536 /* Anonymous */) {
                        writeAnonymousType(type, flags);
                    }
                    else if (type.flags & 256 /* StringLiteral */) {
                        writer.writeStringLiteral("\"" + ts.escapeString(type.text) + "\"");
                    }
                    else {
                        // Should never get here
                        // { ... }
                        writePunctuation(writer, 15 /* OpenBraceToken */);
                        writeSpace(writer);
                        writePunctuation(writer, 22 /* DotDotDotToken */);
                        writeSpace(writer);
                        writePunctuation(writer, 16 /* CloseBraceToken */);
                    }
                }
                function writeTypeList(types, delimiter) {
                    for (var i = 0; i < types.length; i++) {
                        if (i > 0) {
                            if (delimiter !== 24 /* CommaToken */) {
                                writeSpace(writer);
                            }
                            writePunctuation(writer, delimiter);
                            writeSpace(writer);
                        }
                        writeType(types[i], delimiter === 24 /* CommaToken */ ? 0 /* None */ : 64 /* 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.name)) {
                        buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793056 /* Type */, 0 /* None */, flags);
                    }
                    if (pos < end) {
                        writePunctuation(writer, 25 /* LessThanToken */);
                        writeType(typeArguments[pos], 256 /* InFirstTypeArgument */);
                        pos++;
                        while (pos < end) {
                            writePunctuation(writer, 24 /* CommaToken */);
                            writeSpace(writer);
                            writeType(typeArguments[pos], 0 /* None */);
                            pos++;
                        }
                        writePunctuation(writer, 27 /* GreaterThanToken */);
                    }
                }
                function writeTypeReference(type, flags) {
                    var typeArguments = type.typeArguments || emptyArray;
                    if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) {
                        writeType(typeArguments[0], 64 /* InElementType */);
                        writePunctuation(writer, 19 /* OpenBracketToken */);
                        writePunctuation(writer, 20 /* CloseBracketToken */);
                    }
                    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_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_7 = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
                                do {
                                    i++;
                                } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent_7);
                                // 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_7, typeArguments, start, i, flags);
                                    writePunctuation(writer, 21 /* DotToken */);
                                }
                            }
                        }
                        var typeParameterCount = (type.target.typeParameters || emptyArray).length;
                        writeSymbolTypeReference(type.symbol, typeArguments, i, typeParameterCount, flags);
                    }
                }
                function writeTupleType(type) {
                    writePunctuation(writer, 19 /* OpenBracketToken */);
                    writeTypeList(type.elementTypes, 24 /* CommaToken */);
                    writePunctuation(writer, 20 /* CloseBracketToken */);
                }
                function writeUnionOrIntersectionType(type, flags) {
                    if (flags & 64 /* InElementType */) {
                        writePunctuation(writer, 17 /* OpenParenToken */);
                    }
                    writeTypeList(type.types, type.flags & 16384 /* Union */ ? 47 /* BarToken */ : 46 /* AmpersandToken */);
                    if (flags & 64 /* InElementType */) {
                        writePunctuation(writer, 18 /* 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 */ | 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, 793056 /* Type */, 0 /* None */, flags);
                            }
                            else {
                                // Recursive usage, use any
                                writeKeyword(writer, 117 /* 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 (!symbolStack) {
                                symbolStack = [];
                            }
                            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 */ &&
                            ts.forEach(symbol.declarations, function (declaration) { return declaration.flags & 32 /* Static */; }));
                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
                            (symbol.parent ||
                                ts.forEach(symbol.declarations, function (declaration) {
                                    return declaration.parent.kind === 256 /* SourceFile */ || declaration.parent.kind === 226 /* ModuleBlock */;
                                }));
                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                            // typeof is allowed only for static/non local functions
                            return !!(flags & 2 /* UseTypeOfFunction */) ||
                                (ts.contains(symbolStack, symbol)); // it is type of the symbol uses itself recursively
                        }
                    }
                }
                function writeTypeOfSymbol(type, typeFormatFlags) {
                    writeKeyword(writer, 101 /* TypeOfKeyword */);
                    writeSpace(writer);
                    buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 107455 /* Value */, 0 /* None */, typeFormatFlags);
                }
                function writeIndexSignature(info, keyword) {
                    if (info) {
                        if (info.isReadonly) {
                            writeKeyword(writer, 128 /* ReadonlyKeyword */);
                            writeSpace(writer);
                        }
                        writePunctuation(writer, 19 /* OpenBracketToken */);
                        writer.writeParameter(info.declaration ? ts.declarationNameToString(info.declaration.parameters[0].name) : "x");
                        writePunctuation(writer, 54 /* ColonToken */);
                        writeSpace(writer);
                        writeKeyword(writer, keyword);
                        writePunctuation(writer, 20 /* CloseBracketToken */);
                        writePunctuation(writer, 54 /* ColonToken */);
                        writeSpace(writer);
                        writeType(info.type, 0 /* None */);
                        writePunctuation(writer, 23 /* SemicolonToken */);
                        writer.writeLine();
                    }
                }
                function writePropertyWithModifiers(prop) {
                    if (isReadonlySymbol(prop)) {
                        writeKeyword(writer, 128 /* ReadonlyKeyword */);
                        writeSpace(writer);
                    }
                    buildSymbolDisplay(prop, writer);
                    if (prop.flags & 536870912 /* Optional */) {
                        writePunctuation(writer, 53 /* QuestionToken */);
                    }
                }
                function shouldAddParenthesisAroundFunctionType(callSignature, flags) {
                    if (flags & 64 /* InElementType */) {
                        return true;
                    }
                    else if (flags & 256 /* InFirstTypeArgument */) {
                        // Add parenthesis around function type for the first type argument to avoid ambiguity
                        var typeParameters = callSignature.target && (flags & 32 /* WriteTypeArgumentsOfSignature */) ?
                            callSignature.target.typeParameters : callSignature.typeParameters;
                        return typeParameters && typeParameters.length !== 0;
                    }
                    return false;
                }
                function writeLiteralType(type, flags) {
                    var resolved = resolveStructuredTypeMembers(type);
                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                            writePunctuation(writer, 15 /* OpenBraceToken */);
                            writePunctuation(writer, 16 /* CloseBraceToken */);
                            return;
                        }
                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                            var parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags);
                            if (parenthesizeSignature) {
                                writePunctuation(writer, 17 /* OpenParenToken */);
                            }
                            buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 8 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack);
                            if (parenthesizeSignature) {
                                writePunctuation(writer, 18 /* CloseParenToken */);
                            }
                            return;
                        }
                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                            if (flags & 64 /* InElementType */) {
                                writePunctuation(writer, 17 /* OpenParenToken */);
                            }
                            writeKeyword(writer, 92 /* NewKeyword */);
                            writeSpace(writer);
                            buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 8 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack);
                            if (flags & 64 /* InElementType */) {
                                writePunctuation(writer, 18 /* CloseParenToken */);
                            }
                            return;
                        }
                    }
                    var saveInObjectTypeLiteral = inObjectTypeLiteral;
                    inObjectTypeLiteral = true;
                    writePunctuation(writer, 15 /* OpenBraceToken */);
                    writer.writeLine();
                    writer.increaseIndent();
                    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, 23 /* 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, 23 /* SemicolonToken */);
                        writer.writeLine();
                    }
                    writeIndexSignature(resolved.stringIndexInfo, 132 /* StringKeyword */);
                    writeIndexSignature(resolved.numberIndexInfo, 130 /* NumberKeyword */);
                    for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
                        var p = _e[_d];
                        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_1 = signatures; _f < signatures_1.length; _f++) {
                                var signature = signatures_1[_f];
                                writePropertyWithModifiers(p);
                                buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack);
                                writePunctuation(writer, 23 /* SemicolonToken */);
                                writer.writeLine();
                            }
                        }
                        else {
                            writePropertyWithModifiers(p);
                            writePunctuation(writer, 54 /* ColonToken */);
                            writeSpace(writer);
                            writeType(t, 0 /* None */);
                            writePunctuation(writer, 23 /* SemicolonToken */);
                            writer.writeLine();
                        }
                    }
                    writer.decreaseIndent();
                    writePunctuation(writer, 16 /* CloseBraceToken */);
                    inObjectTypeLiteral = saveInObjectTypeLiteral;
                }
            }
            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, 83 /* ExtendsKeyword */);
                    writeSpace(writer);
                    buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack);
                }
            }
            function buildParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack) {
                var parameterNode = p.valueDeclaration;
                if (ts.isRestParameter(parameterNode)) {
                    writePunctuation(writer, 22 /* DotDotDotToken */);
                }
                if (ts.isBindingPattern(parameterNode.name)) {
                    buildBindingPatternDisplay(parameterNode.name, writer, enclosingDeclaration, flags, symbolStack);
                }
                else {
                    appendSymbolNameOnly(p, writer);
                }
                if (isOptionalParameter(parameterNode)) {
                    writePunctuation(writer, 53 /* QuestionToken */);
                }
                writePunctuation(writer, 54 /* ColonToken */);
                writeSpace(writer);
                buildTypeDisplay(getTypeOfSymbol(p), 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 === 167 /* ObjectBindingPattern */) {
                    writePunctuation(writer, 15 /* OpenBraceToken */);
                    buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); });
                    writePunctuation(writer, 16 /* CloseBraceToken */);
                }
                else if (bindingPattern.kind === 168 /* ArrayBindingPattern */) {
                    writePunctuation(writer, 19 /* OpenBracketToken */);
                    var elements = bindingPattern.elements;
                    buildDisplayForCommaSeparatedList(elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); });
                    if (elements && elements.hasTrailingComma) {
                        writePunctuation(writer, 24 /* CommaToken */);
                    }
                    writePunctuation(writer, 20 /* CloseBracketToken */);
                }
            }
            function buildBindingElementDisplay(bindingElement, writer, enclosingDeclaration, flags, symbolStack) {
                if (bindingElement.kind === 193 /* OmittedExpression */) {
                    return;
                }
                ts.Debug.assert(bindingElement.kind === 169 /* BindingElement */);
                if (bindingElement.propertyName) {
                    writer.writeSymbol(ts.getTextOfNode(bindingElement.propertyName), bindingElement.symbol);
                    writePunctuation(writer, 54 /* ColonToken */);
                    writeSpace(writer);
                }
                if (ts.isBindingPattern(bindingElement.name)) {
                    buildBindingPatternDisplay(bindingElement.name, writer, enclosingDeclaration, flags, symbolStack);
                }
                else {
                    if (bindingElement.dotDotDotToken) {
                        writePunctuation(writer, 22 /* DotDotDotToken */);
                    }
                    appendSymbolNameOnly(bindingElement.symbol, writer);
                }
            }
            function buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, flags, symbolStack) {
                if (typeParameters && typeParameters.length) {
                    writePunctuation(writer, 25 /* LessThanToken */);
                    buildDisplayForCommaSeparatedList(typeParameters, writer, function (p) { return buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack); });
                    writePunctuation(writer, 27 /* GreaterThanToken */);
                }
            }
            function buildDisplayForCommaSeparatedList(list, writer, action) {
                for (var i = 0; i < list.length; i++) {
                    if (i > 0) {
                        writePunctuation(writer, 24 /* CommaToken */);
                        writeSpace(writer);
                    }
                    action(list[i]);
                }
            }
            function buildDisplayForTypeArgumentsAndDelimiters(typeParameters, mapper, writer, enclosingDeclaration, flags, symbolStack) {
                if (typeParameters && typeParameters.length) {
                    writePunctuation(writer, 25 /* LessThanToken */);
                    var flags_1 = 256 /* InFirstTypeArgument */;
                    for (var i = 0; i < typeParameters.length; i++) {
                        if (i > 0) {
                            writePunctuation(writer, 24 /* CommaToken */);
                            writeSpace(writer);
                            flags_1 = 0 /* None */;
                        }
                        buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags_1);
                    }
                    writePunctuation(writer, 27 /* GreaterThanToken */);
                }
            }
            function buildDisplayForParametersAndDelimiters(thisParameter, parameters, writer, enclosingDeclaration, flags, symbolStack) {
                writePunctuation(writer, 17 /* OpenParenToken */);
                if (thisParameter) {
                    buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack);
                }
                for (var i = 0; i < parameters.length; i++) {
                    if (i > 0 || thisParameter) {
                        writePunctuation(writer, 24 /* CommaToken */);
                        writeSpace(writer);
                    }
                    buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack);
                }
                writePunctuation(writer, 18 /* CloseParenToken */);
            }
            function buildTypePredicateDisplay(predicate, writer, enclosingDeclaration, flags, symbolStack) {
                if (ts.isIdentifierTypePredicate(predicate)) {
                    writer.writeParameter(predicate.parameterName);
                }
                else {
                    writeKeyword(writer, 97 /* ThisKeyword */);
                }
                writeSpace(writer);
                writeKeyword(writer, 124 /* IsKeyword */);
                writeSpace(writer);
                buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack);
            }
            function buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack) {
                if (flags & 8 /* WriteArrowStyleSignature */) {
                    writeSpace(writer);
                    writePunctuation(writer, 34 /* EqualsGreaterThanToken */);
                }
                else {
                    writePunctuation(writer, 54 /* ColonToken */);
                }
                writeSpace(writer);
                if (signature.typePredicate) {
                    buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack);
                }
                else {
                    var returnType = getReturnTypeOfSignature(signature);
                    buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
                }
            }
            function buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind, symbolStack) {
                if (kind === 1 /* Construct */) {
                    writeKeyword(writer, 92 /* NewKeyword */);
                    writeSpace(writer);
                }
                if (signature.target && (flags & 32 /* 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);
            }
            return _displayBuilder || (_displayBuilder = {
                buildSymbolDisplay: buildSymbolDisplay,
                buildTypeDisplay: buildTypeDisplay,
                buildTypeParameterDisplay: buildTypeParameterDisplay,
                buildTypePredicateDisplay: buildTypePredicateDisplay,
                buildParameterDisplay: buildParameterDisplay,
                buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
                buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
                buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,
                buildSignatureDisplay: buildSignatureDisplay,
                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 169 /* BindingElement */:
                        return isDeclarationVisible(node.parent.parent);
                    case 218 /* VariableDeclaration */:
                        if (ts.isBindingPattern(node.name) &&
                            !node.name.elements.length) {
                            // If the binding pattern is empty, this variable declaration is not visible
                            return false;
                        }
                    // Otherwise fall through
                    case 225 /* ModuleDeclaration */:
                    case 221 /* ClassDeclaration */:
                    case 222 /* InterfaceDeclaration */:
                    case 223 /* TypeAliasDeclaration */:
                    case 220 /* FunctionDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 229 /* ImportEqualsDeclaration */:
                        // external module augmentation is always visible
                        if (ts.isExternalModuleAugmentation(node)) {
                            return true;
                        }
                        var parent_8 = getDeclarationContainer(node);
                        // If the node is not exported or it is not ambient module element (except import declaration)
                        if (!(ts.getCombinedNodeFlags(node) & 1 /* Export */) &&
                            !(node.kind !== 229 /* ImportEqualsDeclaration */ && parent_8.kind !== 256 /* SourceFile */ && ts.isInAmbientContext(parent_8))) {
                            return isGlobalSourceFile(parent_8);
                        }
                        // Exported members/ambient module elements (exception import declaration) are visible if parent is visible
                        return isDeclarationVisible(parent_8);
                    case 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                        if (node.flags & (8 /* Private */ | 16 /* Protected */)) {
                            // Private/protected properties/methods are not visible
                            return false;
                        }
                    // Public properties/methods are visible if its parents are visible, so const it fall into next case statement
                    case 148 /* Constructor */:
                    case 152 /* ConstructSignature */:
                    case 151 /* CallSignature */:
                    case 153 /* IndexSignature */:
                    case 142 /* Parameter */:
                    case 226 /* ModuleBlock */:
                    case 156 /* FunctionType */:
                    case 157 /* ConstructorType */:
                    case 159 /* TypeLiteral */:
                    case 155 /* TypeReference */:
                    case 160 /* ArrayType */:
                    case 161 /* TupleType */:
                    case 162 /* UnionType */:
                    case 163 /* IntersectionType */:
                    case 164 /* 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 231 /* ImportClause */:
                    case 232 /* NamespaceImport */:
                    case 234 /* ImportSpecifier */:
                        return false;
                    // Type parameters are always visible
                    case 141 /* TypeParameter */:
                    // Source file is always visible
                    case 256 /* SourceFile */:
                        return true;
                    // Export assignments do not create name bindings outside the module
                    case 235 /* ExportAssignment */:
                        return false;
                    default:
                        return false;
                }
            }
        }
        function collectLinkedAliases(node) {
            var exportSymbol;
            if (node.parent && node.parent.kind === 235 /* ExportAssignment */) {
                exportSymbol = resolveName(node.parent, node.text, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */ | 8388608 /* Alias */, ts.Diagnostics.Cannot_find_name_0, node);
            }
            else if (node.parent.kind === 238 /* ExportSpecifier */) {
                var exportSpecifier = node.parent;
                exportSymbol = exportSpecifier.parent.parent.moduleSpecifier ?
                    getExternalModuleMember(exportSpecifier.parent.parent, exportSpecifier) :
                    resolveEntityName(exportSpecifier.propertyName || exportSpecifier.name, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */ | 8388608 /* 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;
                    if (!ts.contains(result, resultNode)) {
                        result.push(resultNode);
                    }
                    if (ts.isInternalModuleImportEqualsDeclaration(declaration)) {
                        // Add the referenced top container visible
                        var internalModuleReference = declaration.moduleReference;
                        var firstIdentifier = getFirstIdentifier(internalModuleReference);
                        var importSymbol = resolveName(declaration, firstIdentifier.text, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */, undefined, undefined);
                        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_2 = resolutionTargets.length;
                for (var i = resolutionCycleStartIndex; i < length_2; 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 */) {
                ts.Debug.assert(!!(target.flags & 1024 /* Class */));
                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.getRootDeclaration(node);
            while (node) {
                switch (node.kind) {
                    case 218 /* VariableDeclaration */:
                    case 219 /* VariableDeclarationList */:
                    case 234 /* ImportSpecifier */:
                    case 233 /* NamedImports */:
                    case 232 /* NamespaceImport */:
                    case 231 /* ImportClause */:
                        node = node.parent;
                        break;
                    default:
                        return 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;
        }
        function isTypeNever(type) {
            return type && (type.flags & 134217728 /* Never */) !== 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 getTextOfPropertyName(name) {
            switch (name.kind) {
                case 69 /* Identifier */:
                    return name.text;
                case 9 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                    return name.text;
                case 140 /* ComputedPropertyName */:
                    if (ts.isStringOrNumericLiteral(name.expression.kind)) {
                        return name.expression.text;
                    }
            }
            return undefined;
        }
        function isComputedNonLiteralName(name) {
            return name.kind === 140 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteral(name.expression.kind);
        }
        /** 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, or if the specified or inferred type is any,
            // infer from the initializer of the binding element if one is present. Otherwise, go with the
            // undefined or any type of the parent.
            if (!parentType || isTypeAny(parentType)) {
                if (declaration.initializer) {
                    return checkExpressionCached(declaration.initializer);
                }
                return parentType;
            }
            var type;
            if (pattern.kind === 167 /* ObjectBindingPattern */) {
                // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                var name_11 = declaration.propertyName || declaration.name;
                if (isComputedNonLiteralName(name_11)) {
                    // computed properties with non-literal names are treated as 'any'
                    return anyType;
                }
                if (declaration.initializer) {
                    getContextualType(declaration.initializer);
                }
                // 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 = getTextOfPropertyName(name_11);
                type = getTypeOfPropertyOfType(parentType, text) ||
                    isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
                    getIndexTypeOfType(parentType, 0 /* String */);
                if (!type) {
                    error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_11));
                    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);
                if (!declaration.dotDotDotToken) {
                    // 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), parentType.elementTypes.length, pattern.elements.length);
                        }
                        else {
                            error(declaration, ts.Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName);
                        }
                        return unknownType;
                    }
                }
                else {
                    // Rest element has an array type with the same element type as the parent type
                    type = createArrayType(elementType);
                }
            }
            // 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 && !(getCombinedTypeFlags(checkExpressionCached(declaration.initializer)) & 32 /* Undefined */)) {
                type = getTypeWithFacts(type, 131072 /* NEUndefined */);
            }
            return type;
        }
        function getTypeForVariableLikeDeclarationFromJSDocComment(declaration) {
            var jsDocType = getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration);
            if (jsDocType) {
                return getTypeFromTypeNode(jsDocType);
            }
        }
        function getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration) {
            // First, see if this node has an @type annotation on it directly.
            var typeTag = ts.getJSDocTypeTag(declaration);
            if (typeTag && typeTag.typeExpression) {
                return typeTag.typeExpression.type;
            }
            if (declaration.kind === 218 /* VariableDeclaration */ &&
                declaration.parent.kind === 219 /* VariableDeclarationList */ &&
                declaration.parent.parent.kind === 200 /* VariableStatement */) {
                // @type annotation might have been on the variable statement, try that instead.
                var annotation = ts.getJSDocTypeTag(declaration.parent.parent);
                if (annotation && annotation.typeExpression) {
                    return annotation.typeExpression.type;
                }
            }
            else if (declaration.kind === 142 /* Parameter */) {
                // If it's a parameter, see if the parent has a jsdoc comment with an @param
                // annotation.
                var paramTag = ts.getCorrespondingJSDocParameterTag(declaration);
                if (paramTag && paramTag.typeExpression) {
                    return paramTag.typeExpression.type;
                }
            }
            return undefined;
        }
        function addOptionality(type, optional) {
            return strictNullChecks && optional ? addTypeKind(type, 32 /* Undefined */) : type;
        }
        // Return the inferred type for a variable, parameter, or property declaration
        function getTypeForVariableLikeDeclaration(declaration, includeOptionality) {
            if (declaration.flags & 134217728 /* JavaScriptFile */) {
                // If this is a variable in a JavaScript file, then use the JSDoc type (if it has
                // one as its type), otherwise fallback to the below standard TS codepaths to
                // try to figure it out.
                var type = getTypeForVariableLikeDeclarationFromJSDocComment(declaration);
                if (type && type !== unknownType) {
                    return type;
                }
            }
            // A variable declared in a for..in statement is always of type string
            if (declaration.parent.parent.kind === 207 /* ForInStatement */) {
                return stringType;
            }
            if (declaration.parent.parent.kind === 208 /* 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.
                return checkRightHandSideOfForOf(declaration.parent.parent.expression) || anyType;
            }
            if (ts.isBindingPattern(declaration.parent)) {
                return getTypeForBindingElement(declaration);
            }
            // Use type from type annotation if one is present
            if (declaration.type) {
                return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
            }
            if (declaration.kind === 142 /* 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 === 150 /* SetAccessor */ && !ts.hasDynamicName(func)) {
                    var getter = ts.getDeclarationOfKind(declaration.parent.symbol, 149 /* 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 = declaration.symbol.name === "this"
                    ? getContextuallyTypedThisType(func)
                    : 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) {
                return addOptionality(checkExpressionCached(declaration.initializer), /*optional*/ declaration.questionToken && includeOptionality);
            }
            // If it is a short-hand property assignment, use the type of the identifier
            if (declaration.kind === 254 /* 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);
            }
            // No type specified and nothing can be inferred
            return undefined;
        }
        // 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) {
            if (element.initializer) {
                var type = checkExpressionCached(element.initializer);
                reportErrorsFromWidening(element, type);
                return getWidenedType(type);
            }
            if (ts.isBindingPattern(element.name)) {
                return getTypeFromBindingPattern(element.name, includePatternInType);
            }
            if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
                reportImplicitAnyError(element, anyType);
            }
            return anyType;
        }
        // Return the type implied by an object binding pattern
        function getTypeFromObjectBindingPattern(pattern, includePatternInType) {
            var members = {};
            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;
                }
                var text = getTextOfPropertyName(name);
                var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0);
                var symbol = createSymbol(flags, text);
                symbol.type = getTypeFromBindingElement(e, includePatternInType);
                symbol.bindingElement = e;
                members[symbol.name] = symbol;
            });
            var result = createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined);
            if (includePatternInType) {
                result.pattern = pattern;
            }
            if (hasComputedProperties) {
                result.flags |= 67108864 /* ObjectLiteralPatternWithComputedProperties */;
            }
            return result;
        }
        // Return the type implied by an array binding pattern
        function getTypeFromArrayBindingPattern(pattern, includePatternInType) {
            var elements = pattern.elements;
            if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) {
                return languageVersion >= 2 /* ES6 */ ? 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 e.kind === 193 /* OmittedExpression */ ? anyType : getTypeFromBindingElement(e, includePatternInType); });
            if (includePatternInType) {
                var result = createNewTupleType(elementTypes);
                result.pattern = pattern;
                return result;
            }
            return createTupleType(elementTypes);
        }
        // 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) {
            return pattern.kind === 167 /* ObjectBindingPattern */
                ? getTypeFromObjectBindingPattern(pattern, includePatternInType)
                : getTypeFromArrayBindingPattern(pattern, includePatternInType);
        }
        // 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 === 253 /* 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 && compilerOptions.noImplicitAny) {
                if (!declarationBelongsToPrivateAmbientMember(declaration)) {
                    reportImplicitAnyError(declaration, type);
                }
            }
            return type;
        }
        function declarationBelongsToPrivateAmbientMember(declaration) {
            var root = ts.getRootDeclaration(declaration);
            var memberDeclaration = root.kind === 142 /* Parameter */ ? root.parent : root;
            return isPrivateWithinAmbient(memberDeclaration);
        }
        function getTypeOfVariableOrParameterOrProperty(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                // Handle prototype property
                if (symbol.flags & 134217728 /* Prototype */) {
                    return links.type = getTypeOfPrototypeProperty(symbol);
                }
                // Handle catch clause variables
                var declaration = symbol.valueDeclaration;
                if (declaration.parent.kind === 252 /* CatchClause */) {
                    return links.type = anyType;
                }
                // Handle export default expressions
                if (declaration.kind === 235 /* ExportAssignment */) {
                    return links.type = checkExpression(declaration.expression);
                }
                // Handle variable, parameter or property
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return unknownType;
                }
                var type = undefined;
                // Handle module.exports = expr or this.p = expr
                if (declaration.kind === 187 /* BinaryExpression */) {
                    type = getUnionType(ts.map(symbol.declarations, function (decl) { return checkExpressionCached(decl.right); }));
                }
                else if (declaration.kind === 172 /* PropertyAccessExpression */) {
                    // Declarations only exist for property access expressions for certain
                    // special assignment kinds
                    if (declaration.parent.kind === 187 /* BinaryExpression */) {
                        // Handle exports.p = expr  or className.prototype.method = expr
                        type = checkExpressionCached(declaration.parent.right);
                    }
                }
                if (type === undefined) {
                    type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true);
                }
                if (!popTypeResolution()) {
                    if (symbol.valueDeclaration.type) {
                        // Variable has type annotation that circularly references the variable itself
                        type = unknownType;
                        error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
                    }
                    else {
                        // Variable has initializer that circularly references the variable itself
                        type = anyType;
                        if (compilerOptions.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));
                        }
                    }
                }
                links.type = type;
            }
            return links.type;
        }
        function getAnnotatedAccessorType(accessor) {
            if (accessor) {
                if (accessor.kind === 149 /* GetAccessor */) {
                    return accessor.type && getTypeFromTypeNode(accessor.type);
                }
                else {
                    var setterTypeAnnotation = ts.getSetAccessorTypeAnnotationNode(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, 149 /* GetAccessor */);
                var setter = ts.getDeclarationOfKind(symbol, 150 /* SetAccessor */);
                if (getter && getter.flags & 134217728 /* JavaScriptFile */) {
                    var jsDocType = getTypeForVariableLikeDeclarationFromJSDocComment(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 (compilerOptions.noImplicitAny) {
                                error(setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation, symbolToString(symbol));
                            }
                            type = anyType;
                        }
                    }
                }
                if (!popTypeResolution()) {
                    type = anyType;
                    if (compilerOptions.noImplicitAny) {
                        var getter_1 = ts.getDeclarationOfKind(symbol, 149 /* 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 getTypeOfFuncClassEnumModule(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                if (symbol.valueDeclaration.kind === 225 /* ModuleDeclaration */ && ts.isShorthandAmbientModule(symbol.valueDeclaration)) {
                    links.type = anyType;
                }
                else {
                    var type = createObjectType(65536 /* Anonymous */, symbol);
                    links.type = strictNullChecks && symbol.flags & 536870912 /* Optional */ ?
                        addTypeKind(type, 32 /* Undefined */) : type;
                }
            }
            return links.type;
        }
        function getTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                links.type = getDeclaredTypeOfEnum(getParentOfSymbol(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) {
                links.type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
            }
            return links.type;
        }
        function getTypeOfSymbol(symbol) {
            if (symbol.flags & 16777216 /* 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 & 8388608 /* Alias */) {
                return getTypeOfAlias(symbol);
            }
            return unknownType;
        }
        function getTargetType(type) {
            return type.flags & 4096 /* Reference */ ? type.target : type;
        }
        function hasBaseType(type, checkBase) {
            return check(type);
            function check(type) {
                var target = getTargetType(type);
                return target === checkBase || ts.forEach(getBaseTypes(target), 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));
                if (!typeParameters) {
                    typeParameters = [tp];
                }
                else if (!ts.contains(typeParameters, tp)) {
                    typeParameters.push(tp);
                }
            }
            return typeParameters;
        }
        // Appends the outer type parameters of a node 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 appendOuterTypeParameters(typeParameters, node) {
            while (true) {
                node = node.parent;
                if (!node) {
                    return typeParameters;
                }
                if (node.kind === 221 /* ClassDeclaration */ || node.kind === 192 /* ClassExpression */ ||
                    node.kind === 220 /* FunctionDeclaration */ || node.kind === 179 /* FunctionExpression */ ||
                    node.kind === 147 /* MethodDeclaration */ || node.kind === 180 /* ArrowFunction */) {
                    var declarations = node.typeParameters;
                    if (declarations) {
                        return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations);
                    }
                }
            }
        }
        // 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, 222 /* InterfaceDeclaration */);
            return appendOuterTypeParameters(undefined, 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 === 222 /* InterfaceDeclaration */ || node.kind === 221 /* ClassDeclaration */ ||
                    node.kind === 192 /* ClassExpression */ || node.kind === 223 /* 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));
        }
        function isConstructorType(type) {
            return type.flags & 80896 /* ObjectType */ && getSignaturesOfType(type, 1 /* Construct */).length > 0;
        }
        function getBaseTypeNodeOfClass(type) {
            return ts.getClassExtendsHeritageClauseElement(type.symbol.valueDeclaration);
        }
        function getConstructorsForTypeArguments(type, typeArgumentNodes) {
            var typeArgCount = typeArgumentNodes ? typeArgumentNodes.length : 0;
            return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (sig.typeParameters ? sig.typeParameters.length : 0) === typeArgCount; });
        }
        function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes) {
            var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes);
            if (typeArgumentNodes) {
                var typeArguments_1 = ts.map(typeArgumentNodes, getTypeFromTypeNode);
                signatures = ts.map(signatures, function (sig) { return getSignatureInstantiation(sig, typeArguments_1); });
            }
            return signatures;
        }
        // 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, or
        // an object type with at least one construct signature.
        function getBaseConstructorTypeOfClass(type) {
            if (!type.resolvedBaseConstructorType) {
                var baseTypeNode = getBaseTypeNodeOfClass(type);
                if (!baseTypeNode) {
                    return type.resolvedBaseConstructorType = undefinedType;
                }
                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
                    return unknownType;
                }
                var baseConstructorType = checkExpression(baseTypeNode.expression);
                if (baseConstructorType.flags & 80896 /* ObjectType */) {
                    // 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 !== unknownType && 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) {
            var isClass = type.symbol.flags & 32 /* Class */;
            var isInterface = type.symbol.flags & 64 /* Interface */;
            if (!type.resolvedBaseTypes) {
                if (!isClass && !isInterface) {
                    ts.Debug.fail("type must be class or interface");
                }
                if (isClass) {
                    resolveBaseTypesOfClass(type);
                }
                if (isInterface) {
                    resolveBaseTypesOfInterface(type);
                }
            }
            return type.resolvedBaseTypes;
        }
        function resolveBaseTypesOfClass(type) {
            type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
            var baseConstructorType = getBaseConstructorTypeOfClass(type);
            if (!(baseConstructorType.flags & 80896 /* ObjectType */)) {
                return;
            }
            var baseTypeNode = getBaseTypeNodeOfClass(type);
            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);
            }
            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);
                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 (!(getTargetType(baseType).flags & (1024 /* Class */ | 2048 /* Interface */))) {
                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;
            }
            if (type.resolvedBaseTypes === emptyArray) {
                type.resolvedBaseTypes = [baseType];
            }
            else {
                type.resolvedBaseTypes.push(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 = outerTypeParameters.length - 1;
                var typeArguments = type.typeArguments;
                return outerTypeParameters[last].symbol !== typeArguments[last].symbol;
            }
            return true;
        }
        function resolveBaseTypesOfInterface(type) {
            type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 222 /* 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 (getTargetType(baseType).flags & (1024 /* Class */ | 2048 /* Interface */)) {
                                if (type !== baseType && !hasBaseType(baseType, type)) {
                                    if (type.resolvedBaseTypes === 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 === 222 /* InterfaceDeclaration */) {
                    if (declaration.flags & 16384 /* 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.isSupportedExpressionWithTypeArguments(node)) {
                                var baseSymbol = resolveEntityName(node.expression, 793056 /* 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 */ ? 1024 /* Class */ : 2048 /* 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 === 1024 /* Class */ || !isIndependentInterface(symbol)) {
                    type.flags |= 4096 /* Reference */;
                    type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters);
                    type.outerTypeParameters = outerTypeParameters;
                    type.localTypeParameters = localTypeParameters;
                    type.instantiations = {};
                    type.instantiations[getTypeListId(type.typeParameters)] = type;
                    type.target = type;
                    type.typeArguments = type.typeParameters;
                    type.thisType = createType(512 /* TypeParameter */ | 33554432 /* ThisType */);
                    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 type = void 0;
                var declaration = ts.getDeclarationOfKind(symbol, 279 /* JSDocTypedefTag */);
                if (declaration) {
                    if (declaration.jsDocTypeLiteral) {
                        type = getTypeFromTypeNode(declaration.jsDocTypeLiteral);
                    }
                    else {
                        type = getTypeFromTypeNode(declaration.typeExpression.type);
                    }
                }
                else {
                    declaration = ts.getDeclarationOfKind(symbol, 223 /* TypeAliasDeclaration */);
                    type = getTypeFromTypeNode(declaration.type);
                }
                if (popTypeResolution()) {
                    links.typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    if (links.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.instantiations = {};
                        links.instantiations[getTypeListId(links.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 getDeclaredTypeOfEnum(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var type = createType(128 /* Enum */);
                type.symbol = symbol;
                links.declaredType = type;
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeParameter(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var type = createType(512 /* TypeParameter */);
                type.symbol = symbol;
                if (!ts.getDeclarationOfKind(symbol, 141 /* TypeParameter */).constraint) {
                    type.constraint = noConstraintType;
                }
                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) {
            ts.Debug.assert((symbol.flags & 16777216 /* Instantiated */) === 0);
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getDeclaredTypeOfClassOrInterface(symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getDeclaredTypeOfTypeAlias(symbol);
            }
            if (symbol.flags & 384 /* Enum */) {
                return getDeclaredTypeOfEnum(symbol);
            }
            if (symbol.flags & 262144 /* TypeParameter */) {
                return getDeclaredTypeOfTypeParameter(symbol);
            }
            if (symbol.flags & 8388608 /* Alias */) {
                return getDeclaredTypeOfAlias(symbol);
            }
            return unknownType;
        }
        // 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 117 /* AnyKeyword */:
                case 132 /* StringKeyword */:
                case 130 /* NumberKeyword */:
                case 120 /* BooleanKeyword */:
                case 133 /* SymbolKeyword */:
                case 103 /* VoidKeyword */:
                case 135 /* UndefinedKeyword */:
                case 93 /* NullKeyword */:
                case 127 /* NeverKeyword */:
                case 166 /* StringLiteralType */:
                    return true;
                case 160 /* ArrayType */:
                    return isIndependentType(node.elementType);
                case 155 /* 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) {
            return node.type && isIndependentType(node.type) || !node.type && !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 !== 148 /* Constructor */ && (!node.type || !isIndependentType(node.type))) {
                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 145 /* PropertyDeclaration */:
                        case 144 /* PropertySignature */:
                            return isIndependentVariableLikeDeclaration(declaration);
                        case 147 /* MethodDeclaration */:
                        case 146 /* MethodSignature */:
                        case 148 /* Constructor */:
                            return isIndependentFunctionLikeDeclaration(declaration);
                    }
                }
            }
            return false;
        }
        function createSymbolTable(symbols) {
            var result = {};
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                result[symbol.name] = symbol;
            }
            return result;
        }
        // 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 = {};
            for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                var symbol = symbols_2[_i];
                result[symbol.name] = 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 (!ts.hasProperty(symbols, s.name)) {
                    symbols[s.name] = s;
                }
            }
        }
        function resolveDeclaredMembers(type) {
            if (!type.declaredProperties) {
                var symbol = type.symbol;
                type.declaredProperties = getNamedMembers(symbol.members);
                type.declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]);
                type.declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]);
                type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
            }
            return type;
        }
        function getTypeWithThisArgument(type, thisArgument) {
            if (type.flags & 4096 /* Reference */) {
                return createTypeReference(type.target, ts.concatenate(type.typeArguments, [thisArgument || type.target.thisType]));
            }
            return type;
        }
        function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) {
            var mapper = identityMapper;
            var members = source.symbol.members;
            var callSignatures = source.declaredCallSignatures;
            var constructSignatures = source.declaredConstructSignatures;
            var stringIndexInfo = source.declaredStringIndexInfo;
            var numberIndexInfo = source.declaredNumberIndexInfo;
            if (!ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
                mapper = createTypeMapper(typeParameters, typeArguments);
                members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
                callSignatures = instantiateList(source.declaredCallSignatures, mapper, instantiateSignature);
                constructSignatures = instantiateList(source.declaredConstructSignatures, mapper, instantiateSignature);
                stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
                numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
            }
            var baseTypes = getBaseTypes(source);
            if (baseTypes.length) {
                if (members === source.symbol.members) {
                    members = 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, getPropertiesOfObjectType(instantiatedBaseType));
                    callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
                    constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
                    stringIndexInfo = stringIndexInfo || getIndexInfoOfType(instantiatedBaseType, 0 /* String */);
                    numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */);
                }
            }
            setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function resolveClassOrInterfaceMembers(type) {
            resolveObjectTypeMembers(type, resolveDeclaredMembers(type), emptyArray, 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, hasStringLiterals) {
            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.hasStringLiterals = hasStringLiterals;
            return sig;
        }
        function cloneSignature(sig) {
            return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
        }
        function getDefaultConstructSignatures(classType) {
            var baseConstructorType = getBaseConstructorTypeOfClass(classType);
            var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */);
            if (baseSignatures.length === 0) {
                return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)];
            }
            var baseTypeNode = getBaseTypeNodeOfClass(classType);
            var typeArguments = ts.map(baseTypeNode.typeArguments, getTypeFromTypeNode);
            var typeArgCount = typeArguments ? typeArguments.length : 0;
            var result = [];
            for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) {
                var baseSig = baseSignatures_1[_i];
                var typeParamCount = baseSig.typeParameters ? baseSig.typeParameters.length : 0;
                if (typeParamCount === typeArgCount) {
                    var sig = typeParamCount ? getSignatureInstantiation(baseSig, typeArguments) : cloneSignature(baseSig);
                    sig.typeParameters = classType.localTypeParameters;
                    sig.resolvedReturnType = classType;
                    result.push(sig);
                }
            }
            return result;
        }
        function createTupleTypeMemberSymbols(memberTypes) {
            var members = {};
            for (var i = 0; i < memberTypes.length; i++) {
                var symbol = createSymbol(4 /* Property */ | 67108864 /* Transient */, "" + i);
                symbol.type = memberTypes[i];
                members[i] = symbol;
            }
            return members;
        }
        function resolveTupleTypeMembers(type) {
            var arrayElementType = getUnionType(type.elementTypes, /*noSubtypeReduction*/ true);
            // Make the tuple type itself the 'this' type by including an extra type argument
            var arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type]));
            var members = createTupleTypeMemberSymbols(type.elementTypes);
            addInheritedMembers(members, arrayType.properties);
            setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo);
        }
        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;
                }
                if (!ts.contains(result, match)) {
                    (result || (result = [])).push(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; }));
                                    s.thisParameter = createTransientSymbol(signature.thisParameter, thisType);
                                }
                                // Clear resolved return type we possibly got from cloneSignature
                                s.resolvedReturnType = undefined;
                                s.unionSignatures = unionSignatures;
                            }
                            (result || (result = [])).push(s);
                        }
                    }
                }
            }
            return result || 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), 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 */);
            setObjectTypeMembers(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 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 = emptyArray;
            var constructSignatures = emptyArray;
            var stringIndexInfo = undefined;
            var numberIndexInfo = undefined;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(t, 0 /* Call */));
                constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(t, 1 /* Construct */));
                stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */));
                numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */));
            }
            setObjectTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function resolveAnonymousTypeMembers(type) {
            var symbol = type.symbol;
            if (type.target) {
                var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
                var callSignatures = instantiateList(getSignaturesOfType(type.target, 0 /* Call */), type.mapper, instantiateSignature);
                var constructSignatures = instantiateList(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper, instantiateSignature);
                var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper);
                var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper);
                setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else if (symbol.flags & 2048 /* TypeLiteral */) {
                var members = symbol.members;
                var callSignatures = getSignaturesOfSymbol(members["__call"]);
                var constructSignatures = getSignaturesOfSymbol(members["__new"]);
                var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
                setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else {
                // Combinations of function, class, enum and module
                var members = emptySymbols;
                var constructSignatures = emptyArray;
                if (symbol.flags & 1952 /* HasExports */) {
                    members = getExportsOfSymbol(symbol);
                }
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
                    if (!constructSignatures.length) {
                        constructSignatures = getDefaultConstructSignatures(classType);
                    }
                    var baseConstructorType = getBaseConstructorTypeOfClass(classType);
                    if (baseConstructorType.flags & 80896 /* ObjectType */) {
                        members = createSymbolTable(getNamedMembers(members));
                        addInheritedMembers(members, getPropertiesOfObjectType(baseConstructorType));
                    }
                }
                var numberIndexInfo = symbol.flags & 384 /* Enum */ ? enumNumberIndexInfo : undefined;
                setObjectTypeMembers(type, members, emptyArray, constructSignatures, undefined, 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);
                }
            }
        }
        function resolveStructuredTypeMembers(type) {
            if (!type.members) {
                if (type.flags & 4096 /* Reference */) {
                    resolveTypeReferenceMembers(type);
                }
                else if (type.flags & (1024 /* Class */ | 2048 /* Interface */)) {
                    resolveClassOrInterfaceMembers(type);
                }
                else if (type.flags & 65536 /* Anonymous */) {
                    resolveAnonymousTypeMembers(type);
                }
                else if (type.flags & 8192 /* Tuple */) {
                    resolveTupleTypeMembers(type);
                }
                else if (type.flags & 16384 /* Union */) {
                    resolveUnionTypeMembers(type);
                }
                else if (type.flags & 32768 /* Intersection */) {
                    resolveIntersectionTypeMembers(type);
                }
            }
            return type;
        }
        /** Return properties of an object type or an empty array for other types */
        function getPropertiesOfObjectType(type) {
            if (type.flags & 80896 /* ObjectType */) {
                return resolveStructuredTypeMembers(type).properties;
            }
            return 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 & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (ts.hasProperty(resolved.members, name)) {
                    var symbol = resolved.members[name];
                    if (symbolIsValue(symbol)) {
                        return symbol;
                    }
                }
            }
        }
        function getPropertiesOfUnionOrIntersectionType(type) {
            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];
                    getPropertyOfUnionOrIntersectionType(type, prop.name);
                }
                // 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 & 16384 /* Union */) {
                    break;
                }
            }
            return type.resolvedProperties ? symbolsToArray(type.resolvedProperties) : emptyArray;
        }
        function getPropertiesOfType(type) {
            type = getApparentType(type);
            return type.flags & 49152 /* UnionOrIntersection */ ? getPropertiesOfUnionOrIntersectionType(type) : getPropertiesOfObjectType(type);
        }
        /**
         * The apparent type of a type parameter is the base constraint instantiated with the type parameter
         * as the type argument for the 'this' type.
         */
        function getApparentTypeOfTypeParameter(type) {
            if (!type.resolvedApparentType) {
                var constraintType = getConstraintOfTypeParameter(type);
                while (constraintType && constraintType.flags & 512 /* TypeParameter */) {
                    constraintType = getConstraintOfTypeParameter(constraintType);
                }
                type.resolvedApparentType = getTypeWithThisArgument(constraintType || emptyObjectType, type);
            }
            return type.resolvedApparentType;
        }
        /**
         * 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) {
            if (type.flags & 512 /* TypeParameter */) {
                type = getApparentTypeOfTypeParameter(type);
            }
            if (type.flags & 258 /* StringLike */) {
                type = globalStringType;
            }
            else if (type.flags & 132 /* NumberLike */) {
                type = globalNumberType;
            }
            else if (type.flags & 8 /* Boolean */) {
                type = globalBooleanType;
            }
            else if (type.flags & 16777216 /* ESSymbol */) {
                type = getGlobalESSymbolType();
            }
            return type;
        }
        function createUnionOrIntersectionProperty(containingType, name) {
            var types = containingType.types;
            var props;
            // Flags we want to propagate to the result if they exist in all source symbols
            var commonFlags = (containingType.flags & 32768 /* Intersection */) ? 536870912 /* Optional */ : 0 /* None */;
            var isReadonly = false;
            for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
                var current = types_2[_i];
                var type = getApparentType(current);
                if (type !== unknownType) {
                    var prop = getPropertyOfType(type, name);
                    if (prop && !(getDeclarationFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */))) {
                        commonFlags &= prop.flags;
                        if (!props) {
                            props = [prop];
                        }
                        else if (!ts.contains(props, prop)) {
                            props.push(prop);
                        }
                        if (isReadonlySymbol(prop)) {
                            isReadonly = true;
                        }
                    }
                    else if (containingType.flags & 16384 /* Union */) {
                        // A union type requires the property to be present in all constituent types
                        return undefined;
                    }
                }
            }
            if (!props) {
                return undefined;
            }
            if (props.length === 1) {
                return props[0];
            }
            var propTypes = [];
            var declarations = [];
            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);
                }
                propTypes.push(getTypeOfSymbol(prop));
            }
            var result = createSymbol(4 /* Property */ |
                67108864 /* Transient */ |
                268435456 /* SyntheticProperty */ |
                commonFlags, name);
            result.containingType = containingType;
            result.declarations = declarations;
            result.isReadonly = isReadonly;
            result.type = containingType.flags & 16384 /* Union */ ? getUnionType(propTypes) : getIntersectionType(propTypes);
            return result;
        }
        function getPropertyOfUnionOrIntersectionType(type, name) {
            var properties = type.resolvedProperties || (type.resolvedProperties = {});
            if (ts.hasProperty(properties, name)) {
                return properties[name];
            }
            var property = createUnionOrIntersectionProperty(type, name);
            if (property) {
                properties[name] = property;
            }
            return property;
        }
        // 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.
        function getPropertyOfType(type, name) {
            type = getApparentType(type);
            if (type.flags & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (ts.hasProperty(resolved.members, name)) {
                    var symbol = resolved.members[name];
                    if (symbolIsValue(symbol)) {
                        return symbol;
                    }
                }
                if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
                    var symbol = getPropertyOfObjectType(globalFunctionType, name);
                    if (symbol) {
                        return symbol;
                    }
                }
                return getPropertyOfObjectType(globalObjectType, name);
            }
            if (type.flags & 49152 /* UnionOrIntersection */) {
                return getPropertyOfUnionOrIntersectionType(type, name);
            }
            return undefined;
        }
        function getSignaturesOfStructuredType(type, kind) {
            if (type.flags & 130048 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
            }
            return 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 & 130048 /* 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 (isObjectLiteralType(type)) {
                var propTypes = [];
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.name)) {
                        propTypes.push(getTypeOfSymbol(prop));
                    }
                }
                if (propTypes.length) {
                    return getUnionType(propTypes);
                }
            }
            return undefined;
        }
        function getTypeParametersFromJSDocTemplate(declaration) {
            if (declaration.flags & 134217728 /* JavaScriptFile */) {
                var templateTag = ts.getJSDocTemplateTag(declaration);
                if (templateTag) {
                    return getTypeParametersFromDeclaration(templateTag.typeParameters);
                }
            }
            return undefined;
        }
        // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
        // type checking functions).
        function getTypeParametersFromDeclaration(typeParameterDeclarations) {
            var result = [];
            ts.forEach(typeParameterDeclarations, function (node) {
                var tp = getDeclaredTypeOfTypeParameter(node.symbol);
                if (!ts.contains(result, tp)) {
                    result.push(tp);
                }
            });
            return result;
        }
        function symbolsToArray(symbols) {
            var result = [];
            for (var id in symbols) {
                if (!isReservedMemberName(id)) {
                    result.push(symbols[id]);
                }
            }
            return result;
        }
        function isJSDocOptionalParameter(node) {
            if (node.flags & 134217728 /* JavaScriptFile */) {
                if (node.type && node.type.kind === 268 /* JSDocOptionalType */) {
                    return true;
                }
                var paramTag = ts.getCorrespondingJSDocParameterTag(node);
                if (paramTag) {
                    if (paramTag.isBracketed) {
                        return true;
                    }
                    if (paramTag.typeExpression) {
                        return paramTag.typeExpression.type.kind === 268 /* JSDocOptionalType */;
                    }
                }
            }
        }
        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;
            }
            return false;
        }
        function createTypePredicateFromTypePredicateNode(node) {
            if (node.parameterName.kind === 69 /* Identifier */) {
                var parameterName = node.parameterName;
                return {
                    kind: 1 /* Identifier */,
                    parameterName: parameterName ? parameterName.text : undefined,
                    parameterIndex: parameterName ? getTypePredicateParameterIndex(node.parent.parameters, parameterName) : undefined,
                    type: getTypeFromTypeNode(node.type)
                };
            }
            else {
                return {
                    kind: 0 /* This */,
                    type: getTypeFromTypeNode(node.type)
                };
            }
        }
        function getSignatureFromDeclaration(declaration) {
            var links = getNodeLinks(declaration);
            if (!links.resolvedSignature) {
                var parameters = [];
                var hasStringLiterals = false;
                var minArgumentCount = -1;
                var thisParameter = undefined;
                var hasThisParameter = void 0;
                var isJSConstructSignature = ts.isJSDocConstructSignature(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, n = declaration.parameters.length; i < n; 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.name, 107455 /* Value */, undefined, undefined);
                        paramSymbol = resolvedSymbol;
                    }
                    if (i === 0 && paramSymbol.name === "this") {
                        hasThisParameter = true;
                        thisParameter = param.symbol;
                    }
                    else {
                        parameters.push(paramSymbol);
                    }
                    if (param.type && param.type.kind === 166 /* StringLiteralType */) {
                        hasStringLiterals = true;
                    }
                    if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
                        if (minArgumentCount < 0) {
                            minArgumentCount = i - (hasThisParameter ? 1 : 0);
                        }
                    }
                    else {
                        // If we see any required parameters, it means the prior ones were not in fact optional.
                        minArgumentCount = -1;
                    }
                }
                // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
                if ((declaration.kind === 149 /* GetAccessor */ || declaration.kind === 150 /* SetAccessor */) &&
                    !ts.hasDynamicName(declaration) &&
                    (!hasThisParameter || !thisParameter)) {
                    var otherKind = declaration.kind === 149 /* GetAccessor */ ? 150 /* SetAccessor */ : 149 /* GetAccessor */;
                    var other = ts.getDeclarationOfKind(declaration.symbol, otherKind);
                    if (other) {
                        thisParameter = getAnnotatedAccessorThisParameter(other);
                    }
                }
                if (minArgumentCount < 0) {
                    minArgumentCount = declaration.parameters.length - (hasThisParameter ? 1 : 0);
                }
                if (isJSConstructSignature) {
                    minArgumentCount--;
                }
                var classType = declaration.kind === 148 /* Constructor */ ?
                    getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol))
                    : undefined;
                var typeParameters = classType ? classType.localTypeParameters :
                    declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
                        getTypeParametersFromJSDocTemplate(declaration);
                var returnType = getSignatureReturnTypeFromDeclaration(declaration, minArgumentCount, isJSConstructSignature, classType);
                var typePredicate = declaration.type && declaration.type.kind === 154 /* TypePredicate */ ?
                    createTypePredicateFromTypePredicateNode(declaration.type) :
                    undefined;
                links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, ts.hasRestParameter(declaration), hasStringLiterals);
            }
            return links.resolvedSignature;
        }
        function getSignatureReturnTypeFromDeclaration(declaration, minArgumentCount, isJSConstructSignature, classType) {
            if (isJSConstructSignature) {
                return getTypeFromTypeNode(declaration.parameters[0].type);
            }
            else if (classType) {
                return classType;
            }
            else if (declaration.type) {
                return getTypeFromTypeNode(declaration.type);
            }
            if (declaration.flags & 134217728 /* JavaScriptFile */) {
                var type = getReturnTypeFromJSDocComment(declaration);
                if (type && type !== unknownType) {
                    return type;
                }
            }
            // 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 === 149 /* GetAccessor */ && !ts.hasDynamicName(declaration)) {
                var setter = ts.getDeclarationOfKind(declaration.symbol, 150 /* SetAccessor */);
                return getAnnotatedAccessorType(setter);
            }
            if (ts.nodeIsMissing(declaration.body)) {
                return anyType;
            }
        }
        function getSignaturesOfSymbol(symbol) {
            if (!symbol)
                return emptyArray;
            var result = [];
            for (var i = 0, len = symbol.declarations.length; i < len; i++) {
                var node = symbol.declarations[i];
                switch (node.kind) {
                    case 156 /* FunctionType */:
                    case 157 /* ConstructorType */:
                    case 220 /* FunctionDeclaration */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 148 /* Constructor */:
                    case 151 /* CallSignature */:
                    case 152 /* ConstructSignature */:
                    case 153 /* IndexSignature */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                    case 269 /* 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));
                }
                else {
                    type = getReturnTypeFromBody(signature.declaration);
                }
                if (!popTypeResolution()) {
                    type = anyType;
                    if (compilerOptions.noImplicitAny) {
                        var declaration = signature.declaration;
                        if (declaration.name) {
                            error(declaration.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(declaration.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 getRestTypeOfSignature(signature) {
            if (signature.hasRestParameter) {
                var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters));
                if (type.flags & 4096 /* Reference */ && type.target === globalArrayType) {
                    return type.typeArguments[0];
                }
            }
            return anyType;
        }
        function getSignatureInstantiation(signature, typeArguments) {
            return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
        }
        function getErasedSignature(signature) {
            if (!signature.typeParameters)
                return signature;
            if (!signature.erasedSignatureCache) {
                signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
            }
            return signature.erasedSignatureCache;
        }
        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 === 148 /* Constructor */ || signature.declaration.kind === 152 /* ConstructSignature */;
                var type = createObjectType(65536 /* Anonymous */ | 262144 /* FromSignature */);
                type.members = emptySymbols;
                type.properties = emptyArray;
                type.callSignatures = !isConstructor ? [signature] : emptyArray;
                type.constructSignatures = isConstructor ? [signature] : emptyArray;
                signature.isolatedSignatureType = type;
            }
            return signature.isolatedSignatureType;
        }
        function getIndexSymbol(symbol) {
            return symbol.members["__index"];
        }
        function getIndexDeclarationOfSymbol(symbol, kind) {
            var syntaxKind = kind === 1 /* Number */ ? 130 /* NumberKeyword */ : 132 /* 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, (declaration.flags & 64 /* Readonly */) !== 0, declaration);
            }
            return undefined;
        }
        function getConstraintDeclaration(type) {
            return ts.getDeclarationOfKind(type.symbol, 141 /* TypeParameter */).constraint;
        }
        function hasConstraintReferenceTo(type, target) {
            var checked;
            while (type && !(type.flags & 33554432 /* ThisType */) && type.flags & 512 /* TypeParameter */ && !ts.contains(checked, type)) {
                if (type === target) {
                    return true;
                }
                (checked || (checked = [])).push(type);
                var constraintDeclaration = getConstraintDeclaration(type);
                type = constraintDeclaration && getTypeFromTypeNode(constraintDeclaration);
            }
            return false;
        }
        function getConstraintOfTypeParameter(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);
                    var constraint = getTypeFromTypeNode(constraintDeclaration);
                    if (hasConstraintReferenceTo(constraint, typeParameter)) {
                        error(constraintDeclaration, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
                        constraint = unknownType;
                    }
                    typeParameter.constraint = constraint;
                }
            }
            return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;
        }
        function getParentSymbolOfTypeParameter(typeParameter) {
            return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 141 /* TypeParameter */).parent);
        }
        function getTypeListId(types) {
            if (types) {
                switch (types.length) {
                    case 1:
                        return "" + types[0].id;
                    case 2:
                        return types[0].id + "," + types[1].id;
                    default:
                        var result = "";
                        for (var i = 0; i < types.length; i++) {
                            if (i > 0) {
                                result += ",";
                            }
                            result += types[i].id;
                        }
                        return result;
                }
            }
            return "";
        }
        // 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_3 = types; _i < types_3.length; _i++) {
                var type = types_3[_i];
                if (!(type.flags & excludeKinds)) {
                    result |= type.flags;
                }
            }
            return result & 14680064 /* PropagatingFlags */;
        }
        function createTypeReference(target, typeArguments) {
            var id = getTypeListId(typeArguments);
            var type = target.instantiations[id];
            if (!type) {
                var propagatedFlags = typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
                var flags = 4096 /* Reference */ | propagatedFlags;
                type = target.instantiations[id] = createObjectType(flags, target.symbol);
                type.target = target;
                type.typeArguments = typeArguments;
            }
            return type;
        }
        // Get type from reference to class or interface
        function getTypeFromClassOrInterfaceReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
            var typeParameters = type.localTypeParameters;
            if (typeParameters) {
                if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) {
                    error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */), 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.
                return createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode)));
            }
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
                return unknownType;
            }
            return type;
        }
        // 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) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            if (typeParameters) {
                if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) {
                    error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length);
                    return unknownType;
                }
                var typeArguments = ts.map(node.typeArguments, getTypeFromTypeNode);
                var id = getTypeListId(typeArguments);
                return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments)));
            }
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
                return unknownType;
            }
            return type;
        }
        // Get type from reference to named type that cannot be generic (enum or type parameter)
        function getTypeFromNonGenericTypeReference(node, symbol) {
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
                return unknownType;
            }
            return getDeclaredTypeOfSymbol(symbol);
        }
        function getTypeReferenceName(node) {
            switch (node.kind) {
                case 155 /* TypeReference */:
                    return node.typeName;
                case 267 /* JSDocTypeReference */:
                    return node.name;
                case 194 /* ExpressionWithTypeArguments */:
                    // We only support expressions that are simple qualified names. For other
                    // expressions this produces undefined.
                    if (ts.isSupportedExpressionWithTypeArguments(node)) {
                        return node.expression;
                    }
            }
            return undefined;
        }
        function resolveTypeReferenceName(node, typeReferenceName) {
            if (!typeReferenceName) {
                return unknownSymbol;
            }
            return resolveEntityName(typeReferenceName, 793056 /* Type */) || unknownSymbol;
        }
        function getTypeReferenceType(node, symbol) {
            if (symbol === unknownSymbol) {
                return unknownType;
            }
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getTypeFromClassOrInterfaceReference(node, symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getTypeFromTypeAliasReference(node, symbol);
            }
            if (symbol.flags & 107455 /* Value */ && node.kind === 267 /* JSDocTypeReference */) {
                // A JSDocTypeReference may have resolved to a value (as opposed to a type). In
                // that case, the type of this reference is just the type of the value we resolved
                // to.
                return getTypeOfSymbol(symbol);
            }
            return getTypeFromNonGenericTypeReference(node, symbol);
        }
        function getTypeFromTypeReference(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var symbol = void 0;
                var type = void 0;
                if (node.kind === 267 /* JSDocTypeReference */) {
                    var typeReferenceName = getTypeReferenceName(node);
                    symbol = resolveTypeReferenceName(node, typeReferenceName);
                    type = getTypeReferenceType(node, symbol);
                    links.resolvedSymbol = symbol;
                    links.resolvedType = type;
                }
                else {
                    // We only support expressions that are simple qualified names. For other expressions this produces undefined.
                    var typeNameOrExpression = node.kind === 155 /* TypeReference */ ? node.typeName :
                        ts.isSupportedExpressionWithTypeArguments(node) ? node.expression :
                            undefined;
                    symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, 793056 /* Type */) || unknownSymbol;
                    type = symbol === unknownSymbol ? unknownType :
                        symbol.flags & (32 /* Class */ | 64 /* Interface */) ? getTypeFromClassOrInterfaceReference(node, symbol) :
                            symbol.flags & 524288 /* TypeAlias */ ? getTypeFromTypeAliasReference(node, symbol) :
                                getTypeFromNonGenericTypeReference(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 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 221 /* ClassDeclaration */:
                        case 222 /* InterfaceDeclaration */:
                        case 224 /* EnumDeclaration */:
                            return declaration;
                    }
                }
            }
            if (!symbol) {
                return arity ? emptyGenericType : emptyObjectType;
            }
            var type = getDeclaredTypeOfSymbol(symbol);
            if (!(type.flags & 80896 /* ObjectType */)) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbol.name);
                return arity ? emptyGenericType : emptyObjectType;
            }
            if ((type.typeParameters ? type.typeParameters.length : 0) !== arity) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity);
                return arity ? emptyGenericType : emptyObjectType;
            }
            return type;
        }
        function getGlobalValueSymbol(name) {
            return getGlobalSymbol(name, 107455 /* Value */, ts.Diagnostics.Cannot_find_global_value_0);
        }
        function getGlobalTypeSymbol(name) {
            return getGlobalSymbol(name, 793056 /* Type */, ts.Diagnostics.Cannot_find_global_type_0);
        }
        function getGlobalSymbol(name, meaning, diagnostic) {
            return resolveName(undefined, name, meaning, diagnostic, name);
        }
        function getGlobalType(name, arity) {
            if (arity === void 0) { arity = 0; }
            return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), 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, 1536 /* Namespace */, /*diagnosticMessage*/ undefined);
            var typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, 793056 /* Type */);
            return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol);
        }
        /**
          * Creates a TypeReference for a generic `TypedPropertyDescriptor<T>`.
          */
        function createTypedPropertyDescriptorType(propertyType) {
            var globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType();
            return globalTypedPropertyDescriptorType !== emptyGenericType
                ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType])
                : emptyObjectType;
        }
        /**
         * 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 createIterableType(elementType) {
            return createTypeFromGenericGlobalType(getGlobalIterableType(), [elementType]);
        }
        function createIterableIteratorType(elementType) {
            return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(), [elementType]);
        }
        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;
        }
        function createTupleType(elementTypes) {
            var id = getTypeListId(elementTypes);
            return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes));
        }
        function createNewTupleType(elementTypes) {
            var propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0);
            var type = createObjectType(8192 /* Tuple */ | propagatedFlags);
            type.elementTypes = elementTypes;
            return type;
        }
        function getTypeFromTupleTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = createTupleType(ts.map(node.elementTypes, getTypeFromTypeNode));
            }
            return links.resolvedType;
        }
        function addTypeToSet(typeSet, type, typeSetKind) {
            if (type.flags & typeSetKind) {
                addTypesToSet(typeSet, type.types, typeSetKind);
            }
            else if (type.flags & (1 /* Any */ | 32 /* Undefined */ | 64 /* Null */)) {
                if (type.flags & 1 /* Any */)
                    typeSet.containsAny = true;
                if (type.flags & 32 /* Undefined */)
                    typeSet.containsUndefined = true;
                if (type.flags & 64 /* Null */)
                    typeSet.containsNull = true;
                if (!(type.flags & 2097152 /* ContainsWideningType */))
                    typeSet.containsNonWideningType = true;
            }
            else if (type !== neverType && !ts.contains(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 addTypesToSet(typeSet, types, typeSetKind) {
            for (var _i = 0, types_4 = types; _i < types_4.length; _i++) {
                var type = types_4[_i];
                addTypeToSet(typeSet, type, typeSetKind);
            }
        }
        function isSubtypeOfAny(candidate, types) {
            for (var i = 0, len = types.length; i < len; i++) {
                if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) {
                    return true;
                }
            }
            return false;
        }
        function removeSubtypes(types) {
            var i = types.length;
            while (i > 0) {
                i--;
                if (isSubtypeOfAny(types[i], types)) {
                    types.splice(i, 1);
                }
            }
        }
        // We reduce the constituent type set to only include types that aren't subtypes of other types, unless
        // the noSubtypeReduction flag is specified, in which case we perform a simple deduplication based on
        // object identity. Subtype reduction 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 deduplicated during their declaration. For example, "type Item = string | (() => Item" is
        // a named type that circularly references itself.
        function getUnionType(types, noSubtypeReduction) {
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var typeSet = [];
            addTypesToSet(typeSet, types, 16384 /* Union */);
            if (typeSet.containsAny) {
                return anyType;
            }
            if (strictNullChecks) {
                if (typeSet.containsNull)
                    typeSet.push(nullType);
                if (typeSet.containsUndefined)
                    typeSet.push(undefinedType);
            }
            if (!noSubtypeReduction) {
                removeSubtypes(typeSet);
            }
            if (typeSet.length === 0) {
                return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType :
                    typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType :
                        neverType;
            }
            else if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var type = unionTypes[id];
            if (!type) {
                var propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ 96 /* Nullable */);
                type = unionTypes[id] = createObjectType(16384 /* Union */ | propagatedFlags);
                type.types = typeSet;
            }
            return type;
        }
        function getTypeFromUnionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true);
            }
            return links.resolvedType;
        }
        // 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) {
            if (types.length === 0) {
                return emptyObjectType;
            }
            var typeSet = [];
            addTypesToSet(typeSet, types, 32768 /* Intersection */);
            if (typeSet.containsAny) {
                return anyType;
            }
            if (strictNullChecks) {
                if (typeSet.containsNull)
                    typeSet.push(nullType);
                if (typeSet.containsUndefined)
                    typeSet.push(undefinedType);
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var type = intersectionTypes[id];
            if (!type) {
                var propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ 96 /* Nullable */);
                type = intersectionTypes[id] = createObjectType(32768 /* Intersection */ | propagatedFlags);
                type.types = typeSet;
            }
            return type;
        }
        function getTypeFromIntersectionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode));
            }
            return links.resolvedType;
        }
        function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // Deferred resolution of members is handled by resolveObjectTypeMembers
                links.resolvedType = createObjectType(65536 /* Anonymous */, node.symbol);
            }
            return links.resolvedType;
        }
        function getStringLiteralTypeForText(text) {
            if (ts.hasProperty(stringLiteralTypes, text)) {
                return stringLiteralTypes[text];
            }
            var type = stringLiteralTypes[text] = createType(256 /* StringLiteral */);
            type.text = text;
            return type;
        }
        function getTypeFromStringLiteralTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getStringLiteralTypeForText(ts.unescapeIdentifier(node.text));
            }
            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 getTypeFromJSDocTupleType(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var types = ts.map(node.types, getTypeFromTypeNode);
                links.resolvedType = createTupleType(types);
            }
            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 === 222 /* InterfaceDeclaration */)) {
                if (!(container.flags & 32 /* Static */) &&
                    (container.kind !== 148 /* Constructor */ || ts.isNodeDescendentOf(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 117 /* AnyKeyword */:
                case 258 /* JSDocAllType */:
                case 259 /* JSDocUnknownType */:
                    return anyType;
                case 132 /* StringKeyword */:
                    return stringType;
                case 130 /* NumberKeyword */:
                    return numberType;
                case 120 /* BooleanKeyword */:
                    return booleanType;
                case 133 /* SymbolKeyword */:
                    return esSymbolType;
                case 103 /* VoidKeyword */:
                    return voidType;
                case 135 /* UndefinedKeyword */:
                    return undefinedType;
                case 93 /* NullKeyword */:
                    return nullType;
                case 127 /* NeverKeyword */:
                    return neverType;
                case 165 /* ThisType */:
                case 97 /* ThisKeyword */:
                    return getTypeFromThisTypeNode(node);
                case 166 /* StringLiteralType */:
                    return getTypeFromStringLiteralTypeNode(node);
                case 155 /* TypeReference */:
                case 267 /* JSDocTypeReference */:
                    return getTypeFromTypeReference(node);
                case 154 /* TypePredicate */:
                    return booleanType;
                case 194 /* ExpressionWithTypeArguments */:
                    return getTypeFromTypeReference(node);
                case 158 /* TypeQuery */:
                    return getTypeFromTypeQueryNode(node);
                case 160 /* ArrayType */:
                case 260 /* JSDocArrayType */:
                    return getTypeFromArrayTypeNode(node);
                case 161 /* TupleType */:
                    return getTypeFromTupleTypeNode(node);
                case 162 /* UnionType */:
                case 261 /* JSDocUnionType */:
                    return getTypeFromUnionTypeNode(node);
                case 163 /* IntersectionType */:
                    return getTypeFromIntersectionTypeNode(node);
                case 164 /* ParenthesizedType */:
                case 263 /* JSDocNullableType */:
                case 264 /* JSDocNonNullableType */:
                case 271 /* JSDocConstructorType */:
                case 272 /* JSDocThisType */:
                case 268 /* JSDocOptionalType */:
                    return getTypeFromTypeNode(node.type);
                case 156 /* FunctionType */:
                case 157 /* ConstructorType */:
                case 159 /* TypeLiteral */:
                case 281 /* JSDocTypeLiteral */:
                case 269 /* JSDocFunctionType */:
                case 265 /* JSDocRecordType */:
                    return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                // This function assumes that an identifier or qualified name is a type expression
                // Callers should first ensure this by calling isTypeNode
                case 69 /* Identifier */:
                case 139 /* QualifiedName */:
                    var symbol = getSymbolAtLocation(node);
                    return symbol && getDeclaredTypeOfSymbol(symbol);
                case 262 /* JSDocTupleType */:
                    return getTypeFromJSDocTupleType(node);
                case 270 /* 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 createUnaryTypeMapper(source, target) {
            return function (t) { return t === source ? target : t; };
        }
        function createBinaryTypeMapper(source1, target1, source2, target2) {
            return function (t) { return t === source1 ? target1 : t === source2 ? target2 : t; };
        }
        function createArrayTypeMapper(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) {
            var count = sources.length;
            var mapper = count == 1 ? createUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
                count == 2 ? createBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
                    createArrayTypeMapper(sources, targets);
            mapper.mappedTypes = sources;
            return mapper;
        }
        function createTypeEraser(sources) {
            return createTypeMapper(sources, undefined);
        }
        function getInferenceMapper(context) {
            if (!context.mapper) {
                var mapper = function (t) {
                    var typeParameters = context.typeParameters;
                    for (var i = 0; i < typeParameters.length; i++) {
                        if (t === typeParameters[i]) {
                            context.inferences[i].isFixed = true;
                            return getInferredType(context, i);
                        }
                    }
                    return t;
                };
                mapper.mappedTypes = context.typeParameters;
                mapper.context = context;
                context.mapper = mapper;
            }
            return context.mapper;
        }
        function identityMapper(type) {
            return type;
        }
        function combineTypeMappers(mapper1, mapper2) {
            var mapper = function (t) { return instantiateType(mapper1(t), mapper2); };
            mapper.mappedTypes = mapper1.mappedTypes;
            return mapper;
        }
        function cloneTypeParameter(typeParameter) {
            var result = createType(512 /* 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), instantiateType(signature.resolvedReturnType, mapper), freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
            result.target = signature;
            result.mapper = mapper;
            return result;
        }
        function instantiateSymbol(symbol, mapper) {
            if (symbol.flags & 16777216 /* 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(16777216 /* Instantiated */ | 67108864 /* Transient */ | symbol.flags, symbol.name);
            result.declarations = symbol.declarations;
            result.parent = symbol.parent;
            result.target = symbol;
            result.mapper = mapper;
            if (symbol.valueDeclaration) {
                result.valueDeclaration = symbol.valueDeclaration;
            }
            return result;
        }
        function instantiateAnonymousType(type, mapper) {
            if (mapper.instantiations) {
                var cachedType = mapper.instantiations[type.id];
                if (cachedType) {
                    return cachedType;
                }
            }
            else {
                mapper.instantiations = [];
            }
            // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it
            var result = createObjectType(65536 /* Anonymous */ | 131072 /* Instantiated */, type.symbol);
            result.target = type;
            result.mapper = mapper;
            mapper.instantiations[type.id] = result;
            return result;
        }
        function isSymbolInScopeOfMappedTypeParameter(symbol, mapper) {
            var mappedTypes = mapper.mappedTypes;
            // Starting with the parent of the symbol's declaration, check if the mapper maps any of
            // the type parameters introduced by enclosing declarations. We just pick the first
            // declaration since multiple declarations will all have the same parent anyway.
            var node = symbol.declarations[0].parent;
            while (node) {
                switch (node.kind) {
                    case 156 /* FunctionType */:
                    case 157 /* ConstructorType */:
                    case 220 /* FunctionDeclaration */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 148 /* Constructor */:
                    case 151 /* CallSignature */:
                    case 152 /* ConstructSignature */:
                    case 153 /* IndexSignature */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                    case 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 222 /* InterfaceDeclaration */:
                    case 223 /* TypeAliasDeclaration */:
                        var declaration = node;
                        if (declaration.typeParameters) {
                            for (var _i = 0, _a = declaration.typeParameters; _i < _a.length; _i++) {
                                var d = _a[_i];
                                if (ts.contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) {
                                    return true;
                                }
                            }
                        }
                        if (ts.isClassLike(node) || node.kind === 222 /* InterfaceDeclaration */) {
                            var thisType = getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
                            if (thisType && ts.contains(mappedTypes, thisType)) {
                                return true;
                            }
                        }
                        break;
                    case 225 /* ModuleDeclaration */:
                    case 256 /* SourceFile */:
                        return false;
                }
                node = node.parent;
            }
            return false;
        }
        function instantiateType(type, mapper) {
            if (type && mapper !== identityMapper) {
                if (type.flags & 512 /* TypeParameter */) {
                    return mapper(type);
                }
                if (type.flags & 65536 /* 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. We skip instantiation
                    // if none of the type parameters that are in scope in the type's declaration are mapped by
                    // the given mapper, however we can only do that analysis if the type isn't itself an
                    // instantiation.
                    return type.symbol &&
                        type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) &&
                        (type.flags & 131072 /* Instantiated */ || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ?
                        instantiateAnonymousType(type, mapper) : type;
                }
                if (type.flags & 4096 /* Reference */) {
                    return createTypeReference(type.target, instantiateList(type.typeArguments, mapper, instantiateType));
                }
                if (type.flags & 8192 /* Tuple */) {
                    return createTupleType(instantiateList(type.elementTypes, mapper, instantiateType));
                }
                if (type.flags & 16384 /* Union */) {
                    return getUnionType(instantiateList(type.types, mapper, instantiateType), /*noSubtypeReduction*/ true);
                }
                if (type.flags & 32768 /* Intersection */) {
                    return getIntersectionType(instantiateList(type.types, mapper, instantiateType));
                }
            }
            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 !== 147 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            switch (node.kind) {
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 171 /* ObjectLiteralExpression */:
                    return ts.forEach(node.properties, isContextSensitive);
                case 170 /* ArrayLiteralExpression */:
                    return ts.forEach(node.elements, isContextSensitive);
                case 188 /* ConditionalExpression */:
                    return isContextSensitive(node.whenTrue) ||
                        isContextSensitive(node.whenFalse);
                case 187 /* BinaryExpression */:
                    return node.operatorToken.kind === 52 /* BarBarToken */ &&
                        (isContextSensitive(node.left) || isContextSensitive(node.right));
                case 253 /* PropertyAssignment */:
                    return isContextSensitive(node.initializer);
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 178 /* ParenthesizedExpression */:
                    return isContextSensitive(node.expression);
            }
            return false;
        }
        function isContextSensitiveFunctionLikeDeclaration(node) {
            var areAllParametersUntyped = !ts.forEach(node.parameters, function (p) { return p.type; });
            var isNullaryArrow = node.kind === 180 /* ArrowFunction */ && !node.parameters.length;
            return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
        }
        function isContextSensitiveFunctionOrObjectLiteralMethod(func) {
            return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
        }
        function getTypeWithoutSignatures(type) {
            if (type.flags & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.constructSignatures.length) {
                    var result = createObjectType(65536 /* Anonymous */, type.symbol);
                    result.members = resolved.members;
                    result.properties = resolved.properties;
                    result.callSignatures = emptyArray;
                    result.constructSignatures = emptyArray;
                    type = result;
                }
            }
            return type;
        }
        // TYPE CHECKING
        function isTypeIdenticalTo(source, target) {
            return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined);
        }
        function compareTypesIdentical(source, target) {
            return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesAssignable(source, target) {
            return checkTypeRelatedTo(source, target, assignableRelation, /*errorNode*/ undefined) ? -1 /* True */ : 0 /* False */;
        }
        function isTypeSubtypeOf(source, target) {
            return checkTypeSubtypeOf(source, target, /*errorNode*/ undefined);
        }
        function isTypeAssignableTo(source, target) {
            return checkTypeAssignableTo(source, target, /*errorNode*/ undefined);
        }
        /**
         * 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'.
         */
        function isTypeComparableTo(source, target) {
            return checkTypeComparableTo(source, target, /*errorNode*/ undefined);
        }
        function areTypesComparable(type1, type2) {
            return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
        }
        function checkTypeSubtypeOf(source, target, errorNode, headMessage, containingMessageChain) {
            return checkTypeRelatedTo(source, target, subtypeRelation, errorNode, headMessage, containingMessageChain);
        }
        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, ignoreReturnTypes, /*reportErrors*/ false, /*errorReporter*/ undefined, compareTypesAssignable) !== 0 /* False */;
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesRelated(source, target, 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 */;
            }
            // 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 */;
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType && sourceThisType !== voidType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    // void sources are assignable to anything.
                    var related = 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 s = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source);
                var t = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target);
                var related = compareTypes(s, t, /*reportErrors*/ false) || compareTypes(t, s, reportErrors);
                if (!related) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, sourceParams[i < sourceMax ? i : sourceMax].name, targetParams[i < targetMax ? i : targetMax].name);
                    }
                    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, reportErrors, errorReporter, compareTypes);
                    }
                    else if (ts.isIdentifierTypePredicate(target.typePredicate)) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.Signature_0_must_have_a_type_predicate, signatureToString(source));
                        }
                        return 0 /* False */;
                    }
                }
                else {
                    result &= compareTypes(sourceReturnType, targetReturnType, reportErrors);
                }
            }
            return result;
        }
        function compareTypePredicateRelatedTo(source, target, 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 sourceIdentifierPredicate = source;
                var targetIdentifierPredicate = target;
                if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.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
                || checkTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation, /*errorNode*/ undefined)
                || checkTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation, /*errorNode*/ undefined)) {
                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;
            }
        }
        /**
         * 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 sourceStack;
            var targetStack;
            var maybeStack;
            var expandingFlags;
            var depth = 0;
            var overflow = 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, 128 /* UseFullyQualifiedType */);
                    targetType = typeToString(target, /*enclosingDeclaration*/ undefined, 128 /* UseFullyQualifiedType */);
                }
                if (!message) {
                    message = relation === comparableRelation ?
                        ts.Diagnostics.Type_0_is_not_comparable_to_type_1 :
                        ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
                }
                reportError(message, sourceType, targetType);
            }
            // 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) {
                var result;
                // 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 (!(target.flags & 134217728 /* Never */)) {
                    if (target.flags & 1 /* Any */ || source.flags & 134217728 /* Never */)
                        return -1 /* True */;
                    if (source.flags & 32 /* Undefined */) {
                        if (!strictNullChecks || target.flags & (32 /* Undefined */ | 16 /* Void */))
                            return -1 /* True */;
                    }
                    if (source.flags & 64 /* Null */) {
                        if (!strictNullChecks || target.flags & 64 /* Null */)
                            return -1 /* True */;
                    }
                    if (source.flags & 128 /* Enum */ && target === numberType)
                        return -1 /* True */;
                    if (source.flags & 128 /* Enum */ && target.flags & 128 /* Enum */) {
                        if (result = enumRelatedTo(source, target, reportErrors)) {
                            return result;
                        }
                    }
                    if (source.flags & 256 /* StringLiteral */ && target === stringType)
                        return -1 /* True */;
                    if (relation === assignableRelation || relation === comparableRelation) {
                        if (source.flags & 1 /* Any */)
                            return -1 /* True */;
                        if (source === numberType && target.flags & 128 /* Enum */)
                            return -1 /* True */;
                    }
                    if (source.flags & 8 /* Boolean */ && target.flags & 8 /* Boolean */) {
                        return -1 /* True */;
                    }
                }
                if (source.flags & 1048576 /* FreshObjectLiteral */) {
                    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 (target.flags & 49152 /* UnionOrIntersection */) {
                        source = getRegularTypeOfObjectLiteral(source);
                    }
                }
                var saveErrorInfo = errorInfo;
                // Note that these checks are specifically ordered to produce correct results.
                if (source.flags & 16384 /* Union */) {
                    if (relation === comparableRelation) {
                        result = someTypeRelatedToType(source, target, reportErrors);
                    }
                    else {
                        result = eachTypeRelatedToType(source, target, reportErrors);
                    }
                    if (result) {
                        return result;
                    }
                }
                else if (target.flags & 32768 /* Intersection */) {
                    result = typeRelatedToEachType(source, target, reportErrors);
                    if (result) {
                        return result;
                    }
                }
                else {
                    // It is necessary to try these "some" checks on both sides because there may be nested "each" checks
                    // on either side that need to be prioritized. For example, A | B = (A | B) & (C | D) or
                    // A & B = (A & B) | (C & D).
                    if (source.flags & 32768 /* 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.
                        if (result = someTypeRelatedToType(source, target, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                    if (target.flags & 16384 /* Union */) {
                        if (result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & 16777726 /* Primitive */))) {
                            return result;
                        }
                    }
                }
                if (source.flags & 512 /* TypeParameter */) {
                    var constraint = getConstraintOfTypeParameter(source);
                    if (!constraint || constraint.flags & 1 /* Any */) {
                        constraint = emptyObjectType;
                    }
                    // The constraint may need to be further instantiated with its 'this' type.
                    constraint = getTypeWithThisArgument(constraint, source);
                    // 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 & 4096 /* Reference */ && target.flags & 4096 /* Reference */ && source.target === target.target) {
                        // We have type references to same target type, see if relationship holds for all type arguments
                        if (result = typeArgumentsRelatedTo(source, target, reportErrors)) {
                            return result;
                        }
                    }
                    // Even if relationship doesn't hold for unions, intersections, or generic type references,
                    // it may hold in a structural comparison.
                    var apparentSource = 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 (apparentSource.flags & (80896 /* ObjectType */ | 32768 /* Intersection */) && target.flags & 80896 /* ObjectType */) {
                        // Report structural errors only if we haven't reported any errors yet
                        var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & 16777726 /* Primitive */);
                        if (result = objectTypeRelatedTo(apparentSource, source, target, reportStructuralErrors)) {
                            errorInfo = saveErrorInfo;
                            return result;
                        }
                    }
                }
                if (reportErrors) {
                    reportRelationError(headMessage, source, target);
                }
                return 0 /* False */;
            }
            function isIdenticalTo(source, target) {
                var result;
                if (source.flags & 80896 /* ObjectType */ && target.flags & 80896 /* ObjectType */) {
                    if (source.flags & 4096 /* Reference */ && target.flags & 4096 /* Reference */ && source.target === target.target) {
                        // We have type references to same target type, see if all type arguments are identical
                        if (result = typeArgumentsRelatedTo(source, target, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                    return objectTypeRelatedTo(source, source, target, /*reportErrors*/ false);
                }
                if (source.flags & 16384 /* Union */ && target.flags & 16384 /* Union */ ||
                    source.flags & 32768 /* Intersection */ && target.flags & 32768 /* Intersection */) {
                    if (result = eachTypeRelatedToSomeType(source, target, /*reportErrors*/ false)) {
                        if (result &= eachTypeRelatedToSomeType(target, source, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                }
                return 0 /* False */;
            }
            // 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 the object type is empty and the check is for assignability, if the object type has
            // index signatures, or if the property is actually declared in the object type. In a union or intersection
            // type, a property is considered known if it is known in any constituent type.
            function isKnownProperty(type, name) {
                if (type.flags & 80896 /* ObjectType */) {
                    var resolved = resolveStructuredTypeMembers(type);
                    if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
                        resolved.stringIndexInfo ||
                        (resolved.numberIndexInfo && isNumericLiteralName(name)) ||
                        getPropertyOfType(type, name)) {
                        return true;
                    }
                }
                else if (type.flags & 49152 /* UnionOrIntersection */) {
                    for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                        var t = _a[_i];
                        if (isKnownProperty(t, name)) {
                            return true;
                        }
                    }
                }
                return false;
            }
            function isEmptyObjectType(t) {
                return t.properties.length === 0 &&
                    t.callSignatures.length === 0 &&
                    t.constructSignatures.length === 0 &&
                    !t.stringIndexInfo &&
                    !t.numberIndexInfo;
            }
            function hasExcessProperties(source, target, reportErrors) {
                if (!(target.flags & 67108864 /* ObjectLiteralPatternWithComputedProperties */) && maybeTypeOfKind(target, 80896 /* ObjectType */)) {
                    for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        if (!isKnownProperty(target, prop.name)) {
                            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);
                                errorNode = prop.valueDeclaration;
                                reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target));
                            }
                            return true;
                        }
                    }
                }
                return false;
            }
            function eachTypeRelatedToSomeType(source, target, reportErrors) {
                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;
                var len = targetTypes.length;
                // The null and undefined types are guaranteed to be at the end of the constituent type list. In order
                // to produce the best possible errors we first check the nullable types, such that the last type we
                // check and report errors from is a non-nullable type if one is present.
                while (len >= 2 && targetTypes[len - 1].flags & 96 /* Nullable */) {
                    var related = isRelatedTo(source, targetTypes[len - 1], /*reportErrors*/ false);
                    if (related) {
                        return related;
                    }
                    len--;
                }
                // Now check the non-nullable types and report errors on the last one.
                for (var i = 0; i < len; i++) {
                    var related = isRelatedTo(source, targetTypes[i], reportErrors && i === len - 1);
                    if (related) {
                        return related;
                    }
                }
                return 0 /* False */;
            }
            function typeRelatedToEachType(source, target, reportErrors) {
                var result = -1 /* True */;
                var targetTypes = target.types;
                for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) {
                    var targetType = targetTypes_1[_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;
                var len = sourceTypes.length;
                // The null and undefined types are guaranteed to be at the end of the constituent type list. In order
                // to produce the best possible errors we first check the nullable types, such that the last type we
                // check and report errors from is a non-nullable type if one is present.
                while (len >= 2 && sourceTypes[len - 1].flags & 96 /* Nullable */) {
                    var related = isRelatedTo(sourceTypes[len - 1], target, /*reportErrors*/ false);
                    if (related) {
                        return related;
                    }
                    len--;
                }
                // Now check the non-nullable types and report errors on the last one.
                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, reportErrors) {
                var sources = source.typeArguments || emptyArray;
                var targets = target.typeArguments || 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++) {
                    var related = isRelatedTo(sources[i], targets[i], reportErrors);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            // Determine if two object types are related by structure. 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 objectTypeRelatedTo(source, originalSource, target, reportErrors) {
                if (overflow) {
                    return 0 /* False */;
                }
                var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
                var related = relation[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[id] = 3 /* FailedAndReported */;
                    }
                    else {
                        return related === 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
                    }
                }
                if (depth > 0) {
                    for (var i = 0; i < depth; i++) {
                        // If source and target are already being compared, consider them related with assumptions
                        if (maybeStack[i][id]) {
                            return 1 /* Maybe */;
                        }
                    }
                    if (depth === 100) {
                        overflow = true;
                        return 0 /* False */;
                    }
                }
                else {
                    sourceStack = [];
                    targetStack = [];
                    maybeStack = [];
                    expandingFlags = 0;
                }
                sourceStack[depth] = source;
                targetStack[depth] = target;
                maybeStack[depth] = {};
                maybeStack[depth][id] = 1 /* Succeeded */;
                depth++;
                var saveExpandingFlags = expandingFlags;
                if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth))
                    expandingFlags |= 1;
                if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth))
                    expandingFlags |= 2;
                var result;
                if (expandingFlags === 3) {
                    result = 1 /* Maybe */;
                }
                else {
                    result = propertiesRelatedTo(source, target, reportErrors);
                    if (result) {
                        result &= signaturesRelatedTo(source, target, 0 /* Call */, reportErrors);
                        if (result) {
                            result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportErrors);
                            if (result) {
                                result &= indexTypesRelatedTo(source, originalSource, target, 0 /* String */, reportErrors);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, originalSource, target, 1 /* Number */, reportErrors);
                                }
                            }
                        }
                    }
                }
                expandingFlags = saveExpandingFlags;
                depth--;
                if (result) {
                    var maybeCache = maybeStack[depth];
                    // If result is definitely true, copy assumptions to global cache, else copy to next level up
                    var destinationCache = (result === -1 /* True */ || depth === 0) ? relation : maybeStack[depth - 1];
                    ts.copyMap(maybeCache, destinationCache);
                }
                else {
                    // A false result goes straight into global cache (when something is false under assumptions it
                    // will also be false without assumptions)
                    relation[id] = reportErrors ? 3 /* FailedAndReported */ : 2 /* Failed */;
                }
                return result;
            }
            function propertiesRelatedTo(source, target, reportErrors) {
                if (relation === identityRelation) {
                    return propertiesIdenticalTo(source, target);
                }
                var result = -1 /* True */;
                var properties = getPropertiesOfObjectType(target);
                var requireOptionalProperties = relation === subtypeRelation && !(source.flags & 524288 /* ObjectLiteral */);
                for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) {
                    var targetProp = properties_1[_i];
                    var sourceProp = getPropertyOfType(source, targetProp.name);
                    if (sourceProp !== targetProp) {
                        if (!sourceProp) {
                            if (!(targetProp.flags & 536870912 /* Optional */) || requireOptionalProperties) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_is_missing_in_type_1, symbolToString(targetProp), typeToString(source));
                                }
                                return 0 /* False */;
                            }
                        }
                        else if (!(targetProp.flags & 134217728 /* Prototype */)) {
                            var sourcePropFlags = getDeclarationFlagsFromSymbol(sourceProp);
                            var targetPropFlags = getDeclarationFlagsFromSymbol(targetProp);
                            if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) {
                                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 */) {
                                var sourceDeclaredInClass = sourceProp.parent && sourceProp.parent.flags & 32 /* Class */;
                                var sourceClass = sourceDeclaredInClass ? getDeclaredTypeOfSymbol(getParentOfSymbol(sourceProp)) : undefined;
                                var targetClass = getDeclaredTypeOfSymbol(getParentOfSymbol(targetProp));
                                if (!sourceClass || !hasBaseType(sourceClass, targetClass)) {
                                    if (reportErrors) {
                                        reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(sourceClass || source), typeToString(targetClass));
                                    }
                                    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;
                            if (sourceProp.flags & 536870912 /* Optional */ && !(targetProp.flags & 536870912 /* 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;
            }
            function propertiesIdenticalTo(source, target) {
                if (!(source.flags & 80896 /* ObjectType */ && target.flags & 80896 /* ObjectType */)) {
                    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.name);
                    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;
                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, 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, reportErrors) {
                return compareSignaturesRelated(source, target, /*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, len = sourceSignatures.length; i < len; 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.name)) {
                        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, originalSource, target, kind, reportErrors) {
                if (relation === identityRelation) {
                    return indexTypesIdenticalTo(source, target, kind);
                }
                var targetInfo = getIndexInfoOfType(target, kind);
                if (!targetInfo || ((targetInfo.type.flags & 1 /* Any */) && !(originalSource.flags & 16777726 /* Primitive */))) {
                    // 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 (isObjectLiteralType(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 enumRelatedTo(source, target, reportErrors) {
                if (source.symbol.name !== target.symbol.name ||
                    source.symbol.flags & 128 /* ConstEnum */ ||
                    target.symbol.flags & 128 /* ConstEnum */) {
                    return 0 /* False */;
                }
                var targetEnumType = getTypeOfSymbol(target.symbol);
                for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(source.symbol)); _i < _a.length; _i++) {
                    var property = _a[_i];
                    if (property.flags & 8 /* EnumMember */) {
                        var targetProperty = getPropertyOfType(targetEnumType, property.name);
                        if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Property_0_is_missing_in_type_1, property.name, typeToString(target, /*enclosingDeclaration*/ undefined, 128 /* UseFullyQualifiedType */));
                            }
                            return 0 /* False */;
                        }
                    }
                }
                return -1 /* True */;
            }
            function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) {
                if (!sourceSignature.declaration || !targetSignature.declaration) {
                    return true;
                }
                var sourceAccessibility = sourceSignature.declaration.flags & (8 /* Private */ | 16 /* Protected */);
                var targetAccessibility = targetSignature.declaration.flags & (8 /* Private */ | 16 /* Protected */);
                // 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 true if the given type is the constructor type for an abstract class
        function isAbstractConstructorType(type) {
            if (type.flags & 65536 /* Anonymous */) {
                var symbol = type.symbol;
                if (symbol && symbol.flags & 32 /* Class */) {
                    var declaration = getClassLikeDeclarationOfSymbol(symbol);
                    if (declaration && declaration.flags & 128 /* Abstract */) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case
        // when structural type comparisons have been started for 10 or more instantiations of the same generic type. 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 10 levels, but unequal at
        // some level beyond that.
        function isDeeplyNestedGeneric(type, stack, depth) {
            // We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
            if (type.flags & (4096 /* Reference */ | 131072 /* Instantiated */) && depth >= 5) {
                var symbol = type.symbol;
                var count = 0;
                for (var i = 0; i < depth; i++) {
                    var t = stack[i];
                    if (t.flags & (4096 /* Reference */ | 131072 /* Instantiated */) && 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 = getDeclarationFlagsFromSymbol(sourceProp) & (8 /* Private */ | 16 /* Protected */);
            var targetPropAccessibility = getDeclarationFlagsFromSymbol(targetProp) & (8 /* Private */ | 16 /* Protected */);
            if (sourcePropAccessibility !== targetPropAccessibility) {
                return 0 /* False */;
            }
            if (sourcePropAccessibility) {
                if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
                    return 0 /* False */;
                }
            }
            else {
                if ((sourceProp.flags & 536870912 /* Optional */) !== (targetProp.flags & 536870912 /* 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).
            if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (source.hasRestParameter && !target.hasRestParameter ||
                source.hasRestParameter === target.hasRestParameter && 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 ((source.typeParameters ? source.typeParameters.length : 0) !== (target.typeParameters ? target.typeParameters.length : 0)) {
                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 isSupertypeOfEach(candidate, types) {
            for (var _i = 0, types_5 = types; _i < types_5.length; _i++) {
                var t = types_5[_i];
                if (candidate !== t && !isTypeSubtypeOf(t, candidate))
                    return false;
            }
            return true;
        }
        function getCombinedFlagsOfTypes(types) {
            var flags = 0;
            for (var _i = 0, types_6 = types; _i < types_6.length; _i++) {
                var t = types_6[_i];
                flags |= t.flags;
            }
            return flags;
        }
        function getCommonSupertype(types) {
            if (!strictNullChecks) {
                return ts.forEach(types, function (t) { return isSupertypeOfEach(t, types) ? t : undefined; });
            }
            var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 96 /* Nullable */); });
            if (!primaryTypes.length) {
                return getUnionType(types);
            }
            var supertype = ts.forEach(primaryTypes, function (t) { return isSupertypeOfEach(t, primaryTypes) ? t : undefined; });
            return supertype && addTypeKind(supertype, getCombinedFlagsOfTypes(types) & 96 /* Nullable */);
        }
        function reportNoCommonSupertypeError(types, errorLocation, errorMessageChainHead) {
            // The downfallType/bestSupertypeDownfallType is the first type that caused a particular candidate
            // to not be the common supertype. So if it weren't for this one downfallType (and possibly others),
            // the type in question could have been the common supertype.
            var bestSupertype;
            var bestSupertypeDownfallType;
            var bestSupertypeScore = 0;
            for (var i = 0; i < types.length; i++) {
                var score = 0;
                var downfallType = undefined;
                for (var j = 0; j < types.length; j++) {
                    if (isTypeSubtypeOf(types[j], types[i])) {
                        score++;
                    }
                    else if (!downfallType) {
                        downfallType = types[j];
                    }
                }
                ts.Debug.assert(!!downfallType, "If there is no common supertype, each type should have a downfallType");
                if (score > bestSupertypeScore) {
                    bestSupertype = types[i];
                    bestSupertypeDownfallType = downfallType;
                    bestSupertypeScore = score;
                }
                // types.length - 1 is the maximum score, given that getCommonSupertype returned false
                if (bestSupertypeScore === types.length - 1) {
                    break;
                }
            }
            // In the following errors, the {1} slot is before the {0} slot because checkTypeSubtypeOf supplies the
            // subtype as the first argument to the error
            checkTypeSubtypeOf(bestSupertypeDownfallType, bestSupertype, errorLocation, ts.Diagnostics.Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0, errorMessageChainHead);
        }
        function isArrayType(type) {
            return type.flags & 4096 /* 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 type.flags & 4096 /* Reference */ && (type.target === globalArrayType || type.target === globalReadonlyArrayType) ||
                !(type.flags & 96 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType);
        }
        function isTupleLikeType(type) {
            return !!getPropertyOfType(type, "0");
        }
        function isStringLiteralUnionType(type) {
            return type.flags & 256 /* StringLiteral */ ? true :
                type.flags & 16384 /* Union */ ? ts.forEach(type.types, isStringLiteralUnionType) :
                    false;
        }
        /**
         * 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 !!(type.flags & 8192 /* Tuple */);
        }
        function getCombinedTypeFlags(type) {
            return type.flags & 16384 /* Union */ ? getCombinedFlagsOfTypes(type.types) : type.flags;
        }
        function addTypeKind(type, kind) {
            if ((getCombinedTypeFlags(type) & kind) === kind) {
                return type;
            }
            var types = [type];
            if (kind & 2 /* String */)
                types.push(stringType);
            if (kind & 4 /* Number */)
                types.push(numberType);
            if (kind & 8 /* Boolean */)
                types.push(booleanType);
            if (kind & 16 /* Void */)
                types.push(voidType);
            if (kind & 32 /* Undefined */)
                types.push(undefinedType);
            if (kind & 64 /* Null */)
                types.push(nullType);
            return getUnionType(types);
        }
        function getNonNullableType(type) {
            return strictNullChecks ? getTypeWithFacts(type, 524288 /* NEUndefinedOrNull */) : type;
        }
        /**
         * Return true if type was inferred from an object literal or written as an object type literal
         * with no call or construct signatures.
         */
        function isObjectLiteralType(type) {
            return type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */)) !== 0 &&
                getSignaturesOfType(type, 0 /* Call */).length === 0 &&
                getSignaturesOfType(type, 1 /* Construct */).length === 0;
        }
        function createTransientSymbol(source, type) {
            var symbol = createSymbol(source.flags | 67108864 /* Transient */, source.name);
            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 = {};
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var property = _a[_i];
                var original = getTypeOfSymbol(property);
                var updated = f(original);
                members[property.name] = updated === original ? property : createTransientSymbol(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 (!(type.flags & 1048576 /* FreshObjectLiteral */)) {
                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 /* FreshObjectLiteral */;
            type.regularType = regularNew;
            return regularNew;
        }
        function getWidenedTypeOfObjectLiteral(type) {
            var members = transformTypeOfMembers(type, function (prop) {
                var widened = getWidenedType(prop);
                return prop === widened ? prop : widened;
            });
            var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            return createAnonymousType(type.symbol, members, emptyArray, emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
        }
        function getWidenedConstituentType(type) {
            return type.flags & 96 /* Nullable */ ? type : getWidenedType(type);
        }
        function getWidenedType(type) {
            if (type.flags & 6291456 /* RequiresWidening */) {
                if (type.flags & 96 /* Nullable */) {
                    return anyType;
                }
                if (type.flags & 524288 /* ObjectLiteral */) {
                    return getWidenedTypeOfObjectLiteral(type);
                }
                if (type.flags & 16384 /* Union */) {
                    return getUnionType(ts.map(type.types, getWidenedConstituentType), /*noSubtypeReduction*/ true);
                }
                if (isArrayType(type)) {
                    return createArrayType(getWidenedType(type.typeArguments[0]));
                }
                if (isTupleType(type)) {
                    return createTupleType(ts.map(type.elementTypes, 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 & 16384 /* Union */) {
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (reportWideningErrorsInType(t)) {
                        errorReported = true;
                    }
                }
            }
            if (isArrayType(type)) {
                return reportWideningErrorsInType(type.typeArguments[0]);
            }
            if (isTupleType(type)) {
                for (var _b = 0, _c = type.elementTypes; _b < _c.length; _b++) {
                    var t = _c[_b];
                    if (reportWideningErrorsInType(t)) {
                        errorReported = true;
                    }
                }
            }
            if (type.flags & 524288 /* 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, p.name, typeToString(getWidenedType(t)));
                        }
                        errorReported = true;
                    }
                }
            }
            return errorReported;
        }
        function reportImplicitAnyError(declaration, type) {
            var typeAsString = typeToString(getWidenedType(type));
            var diagnostic;
            switch (declaration.kind) {
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                    diagnostic = ts.Diagnostics.Member_0_implicitly_has_an_1_type;
                    break;
                case 142 /* 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 169 /* BindingElement */:
                    diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type;
                    break;
                case 220 /* FunctionDeclaration */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 179 /* FunctionExpression */:
                case 180 /* 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(declaration.name), typeAsString);
        }
        function reportErrorsFromWidening(declaration, type) {
            if (produceDiagnostics && compilerOptions.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(typeParameters, inferUnionTypes) {
            var inferences = ts.map(typeParameters, createTypeInferencesObject);
            return {
                typeParameters: typeParameters,
                inferUnionTypes: inferUnionTypes,
                inferences: inferences,
                inferredTypes: new Array(typeParameters.length)
            };
        }
        function createTypeInferencesObject() {
            return {
                primary: undefined,
                secondary: undefined,
                isFixed: false
            };
        }
        function inferTypes(context, source, target) {
            var sourceStack;
            var targetStack;
            var depth = 0;
            var inferiority = 0;
            var visited = {};
            inferFromTypes(source, target);
            function isInProcess(source, target) {
                for (var i = 0; i < depth; i++) {
                    if (source === sourceStack[i] && target === targetStack[i]) {
                        return true;
                    }
                }
                return false;
            }
            function inferFromTypes(source, target) {
                if (source.flags & 16384 /* Union */ && target.flags & 16384 /* Union */ ||
                    source.flags & 32768 /* Intersection */ && target.flags & 32768 /* Intersection */) {
                    // Source and target are both unions or both intersections. First, find each
                    // target constituent type that has an identically matching source constituent
                    // type, and for each such target constituent 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.
                    var matchingTypes = void 0;
                    for (var _i = 0, _a = target.types; _i < _a.length; _i++) {
                        var t = _a[_i];
                        if (typeIdenticalToSomeType(t, source.types)) {
                            (matchingTypes || (matchingTypes = [])).push(t);
                            inferFromTypes(t, t);
                        }
                    }
                    // 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 & 512 /* TypeParameter */) {
                    // 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.
                    if (source.flags & 8388608 /* ContainsAnyFunctionType */) {
                        return;
                    }
                    var typeParameters = context.typeParameters;
                    for (var i = 0; i < typeParameters.length; i++) {
                        if (target === typeParameters[i]) {
                            var inferences = context.inferences[i];
                            if (!inferences.isFixed) {
                                // Any inferences that are made to a type parameter in a union type are inferior
                                // to inferences made to a flat (non-union) type. This is because if we infer to
                                // T | string[], we really don't know if we should be inferring to T or not (because
                                // the correct constituent on the target side could be string[]). Therefore, we put
                                // such inferior inferences into a secondary bucket, and only use them if the primary
                                // bucket is empty.
                                var candidates = inferiority ?
                                    inferences.secondary || (inferences.secondary = []) :
                                    inferences.primary || (inferences.primary = []);
                                if (!ts.contains(candidates, source)) {
                                    candidates.push(source);
                                }
                            }
                            return;
                        }
                    }
                }
                else if (source.flags & 4096 /* Reference */ && target.flags & 4096 /* Reference */ && source.target === target.target) {
                    // If source and target are references to the same generic type, infer from type arguments
                    var sourceTypes = source.typeArguments || emptyArray;
                    var targetTypes = target.typeArguments || emptyArray;
                    var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
                    for (var i = 0; i < count; i++) {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                }
                else if (source.flags & 8192 /* Tuple */ && target.flags & 8192 /* Tuple */ && source.elementTypes.length === target.elementTypes.length) {
                    // If source and target are tuples of the same size, infer from element types
                    var sourceTypes = source.elementTypes;
                    var targetTypes = target.elementTypes;
                    for (var i = 0; i < sourceTypes.length; i++) {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                }
                else if (target.flags & 49152 /* UnionOrIntersection */) {
                    var targetTypes = target.types;
                    var typeParameterCount = 0;
                    var typeParameter = void 0;
                    // First infer to each type in union or intersection that isn't a type parameter
                    for (var _b = 0, targetTypes_2 = targetTypes; _b < targetTypes_2.length; _b++) {
                        var t = targetTypes_2[_b];
                        if (t.flags & 512 /* TypeParameter */ && ts.contains(context.typeParameters, t)) {
                            typeParameter = t;
                            typeParameterCount++;
                        }
                        else {
                            inferFromTypes(source, t);
                        }
                    }
                    // Next, if target containings a single naked type parameter, make a secondary inference to that type
                    // parameter. This gives meaningful results for union types in co-variant positions and intersection
                    // types in contra-variant positions (such as callback parameters).
                    if (typeParameterCount === 1) {
                        inferiority++;
                        inferFromTypes(source, typeParameter);
                        inferiority--;
                    }
                }
                else if (source.flags & 49152 /* UnionOrIntersection */) {
                    // Source is a union or intersection type, infer from each constituent type
                    var sourceTypes = source.types;
                    for (var _c = 0, sourceTypes_3 = sourceTypes; _c < sourceTypes_3.length; _c++) {
                        var sourceType = sourceTypes_3[_c];
                        inferFromTypes(sourceType, target);
                    }
                }
                else {
                    source = getApparentType(source);
                    if (source.flags & 80896 /* ObjectType */ && (target.flags & 4096 /* Reference */ && target.typeArguments ||
                        target.flags & 8192 /* Tuple */ ||
                        target.flags & 65536 /* Anonymous */ && target.symbol && target.symbol.flags & (8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */))) {
                        // If source is an object type, and target is a type reference with type arguments, a tuple type,
                        // the type of a method, or a type literal, infer from members
                        if (isInProcess(source, target)) {
                            return;
                        }
                        if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
                            return;
                        }
                        var key = source.id + "," + target.id;
                        if (ts.hasProperty(visited, key)) {
                            return;
                        }
                        visited[key] = true;
                        if (depth === 0) {
                            sourceStack = [];
                            targetStack = [];
                        }
                        sourceStack[depth] = source;
                        targetStack[depth] = target;
                        depth++;
                        inferFromProperties(source, target);
                        inferFromSignatures(source, target, 0 /* Call */);
                        inferFromSignatures(source, target, 1 /* Construct */);
                        inferFromIndexTypes(source, target);
                        depth--;
                    }
                }
            }
            function inferFromProperties(source, target) {
                var properties = getPropertiesOfObjectType(target);
                for (var _i = 0, properties_2 = properties; _i < properties_2.length; _i++) {
                    var targetProp = properties_2[_i];
                    var sourceProp = getPropertyOfObjectType(source, targetProp.name);
                    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, inferFromTypes);
                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_7 = types; _i < types_7.length; _i++) {
                var t = types_7[_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 & 16384 /* Union */ ? getUnionType(reducedTypes, /*noSubtypeReduction*/ true) : getIntersectionType(reducedTypes);
        }
        function getInferenceCandidates(context, index) {
            var inferences = context.inferences[index];
            return inferences.primary || inferences.secondary || emptyArray;
        }
        function getInferredType(context, index) {
            var inferredType = context.inferredTypes[index];
            var inferenceSucceeded;
            if (!inferredType) {
                var inferences = getInferenceCandidates(context, index);
                if (inferences.length) {
                    // Infer widened union or supertype, or the unknown type for no common supertype
                    var unionOrSuperType = context.inferUnionTypes ? getUnionType(inferences) : getCommonSupertype(inferences);
                    inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType;
                    inferenceSucceeded = !!unionOrSuperType;
                }
                else {
                    // Infer 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.
                    inferredType = emptyObjectType;
                    inferenceSucceeded = true;
                }
                context.inferredTypes[index] = inferredType;
                // Only do the constraint check if inference succeeded (to prevent cascading errors)
                if (inferenceSucceeded) {
                    var constraint = getConstraintOfTypeParameter(context.typeParameters[index]);
                    if (constraint) {
                        var instantiatedConstraint = instantiateType(constraint, getInferenceMapper(context));
                        if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
                            context.inferredTypes[index] = inferredType = instantiatedConstraint;
                        }
                    }
                }
                else if (context.failedTypeParameterIndex === undefined || context.failedTypeParameterIndex > index) {
                    // If inference failed, it is necessary to record the index of the failed type parameter (the one we are on).
                    // It might be that inference has already failed on a later type parameter on a previous call to inferTypeArguments.
                    // So if this failure is on preceding type parameter, this type parameter is the new failure index.
                    context.failedTypeParameterIndex = index;
                }
            }
            return inferredType;
        }
        function getInferredTypes(context) {
            for (var i = 0; i < context.inferredTypes.length; i++) {
                getInferredType(context, i);
            }
            return context.inferredTypes;
        }
        // EXPRESSION TYPE CHECKING
        function getResolvedSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                links.resolvedSymbol = !ts.nodeIsMissing(node) && resolveName(node, node.text, 107455 /* Value */ | 1048576 /* ExportValue */, ts.Diagnostics.Cannot_find_name_0, node) || 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
            while (node) {
                switch (node.kind) {
                    case 158 /* TypeQuery */:
                        return true;
                    case 69 /* Identifier */:
                    case 139 /* QualifiedName */:
                        node = node.parent;
                        continue;
                    default:
                        return false;
                }
            }
            ts.Debug.fail("should not get here");
        }
        // 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.
        function getFlowCacheKey(node) {
            if (node.kind === 69 /* Identifier */) {
                var symbol = getResolvedSymbol(node);
                return symbol !== unknownSymbol ? "" + getSymbolId(symbol) : undefined;
            }
            if (node.kind === 97 /* ThisKeyword */) {
                return "0";
            }
            if (node.kind === 172 /* PropertyAccessExpression */) {
                var key = getFlowCacheKey(node.expression);
                return key && key + "." + node.name.text;
            }
            return undefined;
        }
        function isNullOrUndefinedLiteral(node) {
            return node.kind === 93 /* NullKeyword */ ||
                node.kind === 69 /* Identifier */ && getResolvedSymbol(node) === undefinedSymbol;
        }
        function getLeftmostIdentifierOrThis(node) {
            switch (node.kind) {
                case 69 /* Identifier */:
                case 97 /* ThisKeyword */:
                    return node;
                case 172 /* PropertyAccessExpression */:
                    return getLeftmostIdentifierOrThis(node.expression);
            }
            return undefined;
        }
        function isMatchingReference(source, target) {
            if (source.kind === target.kind) {
                switch (source.kind) {
                    case 69 /* Identifier */:
                        return getResolvedSymbol(source) === getResolvedSymbol(target);
                    case 97 /* ThisKeyword */:
                        return true;
                    case 172 /* PropertyAccessExpression */:
                        return source.name.text === target.name.text &&
                            isMatchingReference(source.expression, target.expression);
                }
            }
            return false;
        }
        function containsMatchingReference(source, target) {
            while (source.kind === 172 /* PropertyAccessExpression */) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        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 === 172 /* 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 & 16384 /* 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 && declaredType.flags & 16384 /* Union */) {
                var reducedTypes = ts.filter(declaredType.types, function (t) { return typeMaybeAssignableTo(assignedType, t); });
                if (reducedTypes.length) {
                    return reducedTypes.length === 1 ? reducedTypes[0] : getUnionType(reducedTypes);
                }
            }
            return declaredType;
        }
        function getTypeFacts(type) {
            var flags = type.flags;
            if (flags & 258 /* StringLike */) {
                return strictNullChecks ? 4079361 /* StringStrictFacts */ : 4194049 /* StringFacts */;
            }
            if (flags & 132 /* NumberLike */) {
                return strictNullChecks ? 4079234 /* NumberStrictFacts */ : 4193922 /* NumberFacts */;
            }
            if (flags & 8 /* Boolean */) {
                return strictNullChecks ? 4078980 /* BooleanStrictFacts */ : 4193668 /* BooleanFacts */;
            }
            if (flags & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return resolved.callSignatures.length || resolved.constructSignatures.length || isTypeSubtypeOf(type, globalFunctionType) ?
                    strictNullChecks ? 1970144 /* FunctionStrictFacts */ : 4181984 /* FunctionFacts */ :
                    strictNullChecks ? 1972176 /* ObjectStrictFacts */ : 4184016 /* ObjectFacts */;
            }
            if (flags & (16 /* Void */ | 32 /* Undefined */)) {
                return 2457472 /* UndefinedFacts */;
            }
            if (flags & 64 /* Null */) {
                return 2340752 /* NullFacts */;
            }
            if (flags & 16777216 /* ESSymbol */) {
                return strictNullChecks ? 1981320 /* SymbolStrictFacts */ : 4193160 /* SymbolFacts */;
            }
            if (flags & 512 /* TypeParameter */) {
                var constraint = getConstraintOfTypeParameter(type);
                return constraint ? getTypeFacts(constraint) : 4194303 /* All */;
            }
            if (flags & 32768 /* Intersection */) {
                return ts.reduceLeft(type.types, function (flags, type) { return flags |= getTypeFacts(type); }, 0 /* None */);
            }
            return 4194303 /* All */;
        }
        function getTypeWithFacts(type, include) {
            if (!(type.flags & 16384 /* Union */)) {
                return getTypeFacts(type) & include ? type : neverType;
            }
            var firstType;
            var types;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (getTypeFacts(t) & include) {
                    if (!firstType) {
                        firstType = t;
                    }
                    else {
                        if (!types) {
                            types = [firstType];
                        }
                        types.push(t);
                    }
                }
            }
            return firstType ? types ? getUnionType(types, /*noSubtypeReduction*/ true) : firstType : neverType;
        }
        function getTypeWithDefault(type, defaultExpression) {
            if (defaultExpression) {
                var defaultType = checkExpression(defaultExpression);
                return getUnionType([getTypeWithFacts(type, 131072 /* NEUndefined */), defaultType]);
            }
            return type;
        }
        function getTypeOfDestructuredProperty(type, name) {
            var text = 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) ||
                unknownType;
        }
        function getTypeOfDestructuredSpreadElement(type) {
            return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false) || unknownType);
        }
        function getAssignedTypeOfBinaryExpression(node) {
            return node.parent.kind === 170 /* ArrayLiteralExpression */ || node.parent.kind === 253 /* PropertyAssignment */ ?
                getTypeWithDefault(getAssignedType(node), node.right) :
                checkExpression(node.right);
        }
        function getAssignedTypeOfArrayLiteralElement(node, element) {
            return getTypeOfDestructuredArrayElement(getAssignedType(node), ts.indexOf(node.elements, element));
        }
        function getAssignedTypeOfSpreadElement(node) {
            return getTypeOfDestructuredSpreadElement(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 207 /* ForInStatement */:
                    return stringType;
                case 208 /* ForOfStatement */:
                    return checkRightHandSideOfForOf(parent.expression) || unknownType;
                case 187 /* BinaryExpression */:
                    return getAssignedTypeOfBinaryExpression(parent);
                case 181 /* DeleteExpression */:
                    return undefinedType;
                case 170 /* ArrayLiteralExpression */:
                    return getAssignedTypeOfArrayLiteralElement(parent, node);
                case 191 /* SpreadElementExpression */:
                    return getAssignedTypeOfSpreadElement(parent);
                case 253 /* PropertyAssignment */:
                    return getAssignedTypeOfPropertyAssignment(parent);
                case 254 /* ShorthandPropertyAssignment */:
                    return getAssignedTypeOfShorthandPropertyAssignment(parent);
            }
            return unknownType;
        }
        function getInitialTypeOfBindingElement(node) {
            var pattern = node.parent;
            var parentType = getInitialType(pattern.parent);
            var type = pattern.kind === 167 /* ObjectBindingPattern */ ?
                getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) :
                !node.dotDotDotToken ?
                    getTypeOfDestructuredArrayElement(parentType, ts.indexOf(pattern.elements, node)) :
                    getTypeOfDestructuredSpreadElement(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 || checkExpression(node);
        }
        function getInitialTypeOfVariableDeclaration(node) {
            if (node.initializer) {
                return getTypeOfInitializer(node.initializer);
            }
            if (node.parent.parent.kind === 207 /* ForInStatement */) {
                return stringType;
            }
            if (node.parent.parent.kind === 208 /* ForOfStatement */) {
                return checkRightHandSideOfForOf(node.parent.parent.expression) || unknownType;
            }
            return unknownType;
        }
        function getInitialType(node) {
            return node.kind === 218 /* VariableDeclaration */ ?
                getInitialTypeOfVariableDeclaration(node) :
                getInitialTypeOfBindingElement(node);
        }
        function getReferenceFromExpression(node) {
            switch (node.kind) {
                case 178 /* ParenthesizedExpression */:
                    return getReferenceFromExpression(node.expression);
                case 187 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 56 /* EqualsToken */:
                            return getReferenceFromExpression(node.left);
                        case 24 /* CommaToken */:
                            return getReferenceFromExpression(node.right);
                    }
            }
            return node;
        }
        function getTypeOfSwitchClause(clause) {
            if (clause.kind === 249 /* CaseClause */) {
                var expr = clause.expression;
                return expr.kind === 9 /* StringLiteral */ ? getStringLiteralTypeForText(expr.text) : checkExpression(expr);
            }
            return undefined;
        }
        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.
                var types = ts.map(switchStatement.caseBlock.clauses, getTypeOfSwitchClause);
                links.switchTypes = ts.forEach(types, function (t) { return !t || t.flags & 256 /* StringLiteral */; }) ? types : emptyArray;
            }
            return links.switchTypes;
        }
        function eachTypeContainedIn(source, types) {
            return source.flags & 16384 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source);
        }
        function filterType(type, f) {
            return type.flags & 16384 /* Union */ ?
                getUnionType(ts.filter(type.types, f)) :
                f(type) ? type : neverType;
        }
        function getFlowTypeOfReference(reference, declaredType, assumeInitialized, includeOuterFunctions) {
            var key;
            if (!reference.flowNode || assumeInitialized && !(declaredType.flags & 16908175 /* Narrowable */)) {
                return declaredType;
            }
            var initialType = assumeInitialized ? declaredType : addTypeKind(declaredType, 32 /* Undefined */);
            var visitedFlowStart = visitedFlowCount;
            var result = getTypeAtFlowNode(reference.flowNode);
            visitedFlowCount = visitedFlowStart;
            if (reference.parent.kind === 196 /* NonNullExpression */ && getTypeWithFacts(result, 524288 /* NEUndefinedOrNull */) === neverType) {
                return declaredType;
            }
            return result;
            function getTypeAtFlowNode(flow) {
                while (true) {
                    if (flow.flags & 512 /* 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 = visitedFlowStart; i < visitedFlowCount; i++) {
                            if (visitedFlowNodes[i] === flow) {
                                return visitedFlowTypes[i];
                            }
                        }
                    }
                    var type = void 0;
                    if (flow.flags & 16 /* Assignment */) {
                        type = getTypeAtFlowAssignment(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flow.flags & 96 /* Condition */) {
                        type = getTypeAtFlowCondition(flow);
                    }
                    else if (flow.flags & 128 /* SwitchClause */) {
                        type = getTypeAtSwitchClause(flow);
                    }
                    else if (flow.flags & 12 /* Label */) {
                        if (flow.antecedents.length === 1) {
                            flow = flow.antecedents[0];
                            continue;
                        }
                        type = flow.flags & 4 /* BranchLabel */ ?
                            getTypeAtFlowBranchLabel(flow) :
                            getTypeAtFlowLoopLabel(flow);
                    }
                    else if (flow.flags & 2 /* Start */) {
                        // Check if we should continue with the control flow of the containing function.
                        var container = flow.container;
                        if (container && includeOuterFunctions) {
                            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 declared type to reduce follow-on errors.
                        type = declaredType;
                    }
                    if (flow.flags & 512 /* Shared */) {
                        // Record visited node and the associated type in the cache.
                        visitedFlowNodes[visitedFlowCount] = flow;
                        visitedFlowTypes[visitedFlowCount] = type;
                        visitedFlowCount++;
                    }
                    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 ((node.kind === 218 /* VariableDeclaration */ || node.kind === 169 /* BindingElement */) &&
                    reference.kind === 69 /* Identifier */ &&
                    getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(reference)) === getSymbolOfNode(node)) {
                    return declaredType.flags & 16384 /* Union */ ?
                        getAssignmentReducedType(declaredType, getInitialType(node)) :
                        declaredType;
                }
                // If the node is not a variable declaration or binding element, it is an identifier
                // or a dotted name that is the target of an assignment. If we have a match, reduce
                // the declared type by the assigned type.
                if (isMatchingReference(reference, node)) {
                    return declaredType.flags & 16384 /* Union */ ?
                        getAssignmentReducedType(declaredType, getAssignedType(node)) :
                        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 getTypeAtFlowCondition(flow) {
                var type = getTypeAtFlowNode(flow.antecedent);
                if (type !== neverType) {
                    // 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 nothing type, then
                    // we take the type guard as an indication that control could reach here in a
                    // manner not understood by the control flow analyzer (e.g. a function argument
                    // has an invalid type, or a nested function has possibly made an assignment to a
                    // captured variable). We proceed by reverting to the declared type and then
                    // narrow that.
                    var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0;
                    type = narrowType(type, flow.expression, assumeTrue);
                    if (type === neverType) {
                        type = narrowType(declaredType, flow.expression, assumeTrue);
                    }
                }
                return type;
            }
            function getTypeAtSwitchClause(flow) {
                var type = getTypeAtFlowNode(flow.antecedent);
                return narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
            }
            function getTypeAtFlowBranchLabel(flow) {
                var antecedentTypes = [];
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    var type = getTypeAtFlowNode(antecedent);
                    // 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;
                    }
                    if (!ts.contains(antecedentTypes, type)) {
                        antecedentTypes.push(type);
                    }
                }
                return getUnionType(antecedentTypes);
            }
            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] = {});
                if (!key) {
                    key = getFlowCacheKey(reference);
                }
                if (cache[key]) {
                    return cache[key];
                }
                // If this flow loop junction and reference are already being processed, return
                // the union of the types computed for each branch so far. We should never see
                // an empty array here 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) {
                        return getUnionType(flowLoopTypes[i]);
                    }
                }
                // Add the flow loop junction and reference to the in-process stack and analyze
                // each antecedent code path.
                var antecedentTypes = [];
                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 type = getTypeAtFlowNode(antecedent);
                    flowLoopCount--;
                    // 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.
                    if (cache[key]) {
                        return cache[key];
                    }
                    if (!ts.contains(antecedentTypes, type)) {
                        antecedentTypes.push(type);
                    }
                    // 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;
                    }
                }
                return cache[key] = getUnionType(antecedentTypes);
            }
            function narrowTypeByTruthiness(type, expr, assumeTrue) {
                return isMatchingReference(reference, expr) ? getTypeWithFacts(type, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */) : type;
            }
            function narrowTypeByBinaryExpression(type, expr, assumeTrue) {
                switch (expr.operatorToken.kind) {
                    case 56 /* EqualsToken */:
                        return narrowTypeByTruthiness(type, expr.left, assumeTrue);
                    case 30 /* EqualsEqualsToken */:
                    case 31 /* ExclamationEqualsToken */:
                    case 32 /* EqualsEqualsEqualsToken */:
                    case 33 /* ExclamationEqualsEqualsToken */:
                        var left = expr.left;
                        var operator = expr.operatorToken.kind;
                        var right = expr.right;
                        if (isNullOrUndefinedLiteral(right)) {
                            return narrowTypeByNullCheck(type, left, operator, right, assumeTrue);
                        }
                        if (isNullOrUndefinedLiteral(left)) {
                            return narrowTypeByNullCheck(type, right, operator, left, assumeTrue);
                        }
                        if (left.kind === 182 /* TypeOfExpression */ && right.kind === 9 /* StringLiteral */) {
                            return narrowTypeByTypeof(type, left, operator, right, assumeTrue);
                        }
                        if (right.kind === 182 /* TypeOfExpression */ && left.kind === 9 /* StringLiteral */) {
                            return narrowTypeByTypeof(type, right, operator, left, assumeTrue);
                        }
                        if (left.kind === 172 /* PropertyAccessExpression */) {
                            return narrowTypeByDiscriminant(type, left, operator, right, assumeTrue);
                        }
                        if (right.kind === 172 /* PropertyAccessExpression */) {
                            return narrowTypeByDiscriminant(type, right, operator, left, assumeTrue);
                        }
                        break;
                    case 91 /* InstanceOfKeyword */:
                        return narrowTypeByInstanceof(type, expr, assumeTrue);
                    case 24 /* CommaToken */:
                        return narrowType(type, expr.right, assumeTrue);
                }
                return type;
            }
            function narrowTypeByNullCheck(type, target, operator, literal, assumeTrue) {
                // We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' as value
                if (operator === 31 /* ExclamationEqualsToken */ || operator === 33 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(target))) {
                    return type;
                }
                var doubleEquals = operator === 30 /* EqualsEqualsToken */ || operator === 31 /* ExclamationEqualsToken */;
                var facts = doubleEquals ?
                    assumeTrue ? 65536 /* EQUndefinedOrNull */ : 524288 /* NEUndefinedOrNull */ :
                    literal.kind === 93 /* NullKeyword */ ?
                        assumeTrue ? 32768 /* EQNull */ : 262144 /* NENull */ :
                        assumeTrue ? 16384 /* EQUndefined */ : 131072 /* NEUndefined */;
                return getTypeWithFacts(type, facts);
            }
            function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) {
                // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands
                var target = getReferenceFromExpression(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 === 31 /* ExclamationEqualsToken */ || operator === 33 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                if (assumeTrue && !(type.flags & 16384 /* Union */)) {
                    // We narrow a non-union type to an exact primitive type if the non-union type
                    // is a supertype of that primtive type. For example, type 'any' can be narrowed
                    // to one of the primitive types.
                    var targetType = ts.getProperty(typeofTypesByName, literal.text);
                    if (targetType && isTypeSubtypeOf(targetType, type)) {
                        return targetType;
                    }
                }
                var facts = assumeTrue ?
                    ts.getProperty(typeofEQFacts, literal.text) || 64 /* TypeofEQHostObject */ :
                    ts.getProperty(typeofNEFacts, literal.text) || 8192 /* TypeofNEHostObject */;
                return getTypeWithFacts(type, facts);
            }
            function narrowTypeByDiscriminant(type, propAccess, operator, value, assumeTrue) {
                // We have '==', '!=', '===', or '!==' operator with property access as target
                if (!isMatchingReference(reference, propAccess.expression)) {
                    return type;
                }
                var propName = propAccess.name.text;
                var propType = getTypeOfPropertyOfType(type, propName);
                if (!propType || !isStringLiteralUnionType(propType)) {
                    return type;
                }
                var discriminantType = value.kind === 9 /* StringLiteral */ ? getStringLiteralTypeForText(value.text) : checkExpression(value);
                if (!isStringLiteralUnionType(discriminantType)) {
                    return type;
                }
                if (operator === 31 /* ExclamationEqualsToken */ || operator === 33 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                if (assumeTrue) {
                    return filterType(type, function (t) { return areTypesComparable(getTypeOfPropertyOfType(t, propName), discriminantType); });
                }
                if (discriminantType.flags & 256 /* StringLiteral */) {
                    return filterType(type, function (t) { return getTypeOfPropertyOfType(t, propName) !== discriminantType; });
                }
                return type;
            }
            function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) {
                // We have switch statement with property access expression
                if (!isMatchingReference(reference, switchStatement.expression.expression)) {
                    return type;
                }
                var propName = switchStatement.expression.name.text;
                var propType = getTypeOfPropertyOfType(type, propName);
                if (!propType || !isStringLiteralUnionType(propType)) {
                    return type;
                }
                var switchTypes = getSwitchClauseTypes(switchStatement);
                if (!switchTypes.length) {
                    return type;
                }
                var clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
                var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, undefined);
                var caseTypes = hasDefaultClause ? ts.filter(clauseTypes, function (t) { return !!t; }) : clauseTypes;
                var discriminantType = caseTypes.length ? getUnionType(caseTypes) : undefined;
                var caseType = discriminantType && filterType(type, function (t) { return isTypeComparableTo(discriminantType, getTypeOfPropertyOfType(t, propName)); });
                if (!hasDefaultClause) {
                    return caseType;
                }
                var defaultType = filterType(type, function (t) { return !eachTypeContainedIn(getTypeOfPropertyOfType(t, propName), switchTypes); });
                return caseType ? getUnionType([caseType, defaultType]) : defaultType;
            }
            function narrowTypeByInstanceof(type, expr, assumeTrue) {
                var left = getReferenceFromExpression(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;
                }
                // We never narrow type any in an instanceof guard
                if (isTypeAny(type)) {
                    return type;
                }
                // Check that right operand is a function type with a prototype property
                var rightType = checkExpression(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;
                    }
                }
                if (!targetType) {
                    // Target type is type of construct signature
                    var constructSignatures = void 0;
                    if (rightType.flags & 2048 /* Interface */) {
                        constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
                    }
                    else if (rightType.flags & 65536 /* 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);
                }
                return type;
            }
            function getNarrowedType(type, candidate, assumeTrue) {
                if (!assumeTrue) {
                    return type.flags & 16384 /* Union */ ?
                        getUnionType(ts.filter(type.types, function (t) { return !isTypeSubtypeOf(t, candidate); })) :
                        type;
                }
                // If the current type is a union type, remove all constituents that aren't assignable to
                // the candidate type. If one or more constituents remain, return a union of those.
                if (type.flags & 16384 /* Union */) {
                    var assignableConstituents = ts.filter(type.types, function (t) { return isTypeAssignableTo(t, candidate); });
                    if (assignableConstituents.length) {
                        return getUnionType(assignableConstituents);
                    }
                }
                // If the candidate type is assignable to the target type, narrow to the candidate type.
                // Otherwise, if the current type is assignable to the candidate, keep the current type.
                // Otherwise, the types are completely unrelated, so narrow to the empty type.
                var targetType = type.flags & 512 /* TypeParameter */ ? getApparentType(type) : type;
                return isTypeAssignableTo(candidate, targetType) ? candidate :
                    isTypeAssignableTo(type, candidate) ? type :
                        getIntersectionType([type, candidate]);
            }
            function narrowTypeByTypePredicate(type, callExpression, assumeTrue) {
                if (type.flags & 1 /* Any */ || !hasMatchingArgument(callExpression, reference)) {
                    return type;
                }
                var signature = getResolvedSignature(callExpression);
                var predicate = signature.typePredicate;
                if (!predicate) {
                    return type;
                }
                if (ts.isIdentifierTypePredicate(predicate)) {
                    var predicateArgument = callExpression.arguments[predicate.parameterIndex];
                    if (predicateArgument) {
                        if (isMatchingReference(reference, predicateArgument)) {
                            return getNarrowedType(type, predicate.type, assumeTrue);
                        }
                        if (containsMatchingReference(reference, predicateArgument)) {
                            return declaredType;
                        }
                    }
                }
                else {
                    var invokedExpression = skipParenthesizedNodes(callExpression.expression);
                    if (invokedExpression.kind === 173 /* ElementAccessExpression */ || invokedExpression.kind === 172 /* PropertyAccessExpression */) {
                        var accessExpression = invokedExpression;
                        var possibleReference = skipParenthesizedNodes(accessExpression.expression);
                        if (isMatchingReference(reference, possibleReference)) {
                            return getNarrowedType(type, predicate.type, assumeTrue);
                        }
                        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 69 /* Identifier */:
                    case 97 /* ThisKeyword */:
                    case 172 /* PropertyAccessExpression */:
                        return narrowTypeByTruthiness(type, expr, assumeTrue);
                    case 174 /* CallExpression */:
                        return narrowTypeByTypePredicate(type, expr, assumeTrue);
                    case 178 /* ParenthesizedExpression */:
                        return narrowType(type, expr.expression, assumeTrue);
                    case 187 /* BinaryExpression */:
                        return narrowTypeByBinaryExpression(type, expr, assumeTrue);
                    case 185 /* PrefixUnaryExpression */:
                        if (expr.operator === 49 /* ExclamationToken */) {
                            return narrowType(type, expr.operand, !assumeTrue);
                        }
                        break;
                }
                return type;
            }
        }
        function getTypeOfSymbolAtLocation(symbol, location) {
            // 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 === 69 /* Identifier */) {
                if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) {
                    location = location.parent;
                }
                if (ts.isExpression(location) && !ts.isAssignmentTarget(location)) {
                    var type = checkExpression(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
            // hypotherical reference (control flow information is created and attached by the
            // binder), we simply return the declared type of the symbol.
            return getTypeOfSymbol(symbol);
        }
        function skipParenthesizedNodes(expression) {
            while (expression.kind === 178 /* ParenthesizedExpression */) {
                expression = expression.expression;
            }
            return expression;
        }
        function getControlFlowContainer(node) {
            while (true) {
                node = node.parent;
                if (ts.isFunctionLike(node) || node.kind === 226 /* ModuleBlock */ || node.kind === 256 /* SourceFile */ || node.kind === 145 /* PropertyDeclaration */) {
                    return node;
                }
            }
        }
        function isDeclarationIncludedInFlow(reference, declaration, includeOuterFunctions) {
            var declarationContainer = getControlFlowContainer(declaration);
            var container = getControlFlowContainer(reference);
            while (container !== declarationContainer &&
                (container.kind === 179 /* FunctionExpression */ || container.kind === 180 /* ArrowFunction */) &&
                (includeOuterFunctions || ts.getImmediatelyInvokedFunctionExpression(container))) {
                container = getControlFlowContainer(container);
            }
            return container === declarationContainer;
        }
        function checkIdentifier(node) {
            var symbol = getResolvedSymbol(node);
            // 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 (container.kind === 180 /* ArrowFunction */) {
                    if (languageVersion < 2 /* ES6 */) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
                    }
                }
                if (node.flags & 33554432 /* AwaitContext */) {
                    getNodeLinks(container).flags |= 8192 /* CaptureArguments */;
                }
            }
            if (symbol.flags & 8388608 /* Alias */ && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
                markAliasSymbolAsReferenced(symbol);
            }
            var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
            // 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 (languageVersion === 2 /* ES6 */
                && localOrExportSymbol.flags & 32 /* Class */
                && localOrExportSymbol.valueDeclaration.kind === 221 /* ClassDeclaration */
                && ts.nodeIsDecorated(localOrExportSymbol.valueDeclaration)) {
                var container = ts.getContainingClass(node);
                while (container !== undefined) {
                    if (container === localOrExportSymbol.valueDeclaration && container.name !== node) {
                        getNodeLinks(container).flags |= 524288 /* ClassWithBodyScopedClassBinding */;
                        getNodeLinks(node).flags |= 1048576 /* BodyScopedClassBinding */;
                        break;
                    }
                    container = ts.getContainingClass(container);
                }
            }
            checkCollisionWithCapturedSuperVariable(node, node);
            checkCollisionWithCapturedThisVariable(node, node);
            checkNestedBlockScopedBinding(node, symbol);
            var type = getTypeOfSymbol(localOrExportSymbol);
            if (!(localOrExportSymbol.flags & 3 /* Variable */) || ts.isAssignmentTarget(node)) {
                return type;
            }
            var declaration = localOrExportSymbol.valueDeclaration;
            var includeOuterFunctions = isReadonlySymbol(localOrExportSymbol);
            var assumeInitialized = !strictNullChecks || (type.flags & 1 /* Any */) !== 0 || !declaration ||
                ts.getRootDeclaration(declaration).kind === 142 /* Parameter */ || ts.isInAmbientContext(declaration) ||
                !isDeclarationIncludedInFlow(node, declaration, includeOuterFunctions);
            var flowType = getFlowTypeOfReference(node, type, assumeInitialized, includeOuterFunctions);
            if (!assumeInitialized && !(getCombinedTypeFlags(type) & 32 /* Undefined */) && getCombinedTypeFlags(flowType) & 32 /* 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 flowType;
        }
        function isInsideFunction(node, threshold) {
            var current = node;
            while (current && current !== threshold) {
                if (ts.isFunctionLike(current)) {
                    return true;
                }
                current = current.parent;
            }
            return false;
        }
        function checkNestedBlockScopedBinding(node, symbol) {
            if (languageVersion >= 2 /* ES6 */ ||
                (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 ||
                symbol.valueDeclaration.parent.kind === 252 /* 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 === 206 /* ForStatement */ &&
                    ts.getAncestor(symbol.valueDeclaration, 219 /* 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) {
            var current = node;
            // skip parenthesized nodes
            while (current.parent.kind === 178 /* 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 === 185 /* PrefixUnaryExpression */ || current.parent.kind === 186 /* PostfixUnaryExpression */)) {
                var expr = current.parent;
                isAssigned = expr.operator === 41 /* PlusPlusToken */ || expr.operator === 42 /* 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
            while (current !== container) {
                if (current === container.statement) {
                    return true;
                }
                else {
                    current = current.parent;
                }
            }
            return false;
        }
        function captureLexicalThis(node, container) {
            getNodeLinks(node).flags |= 2 /* LexicalThis */;
            if (container.kind === 145 /* PropertyDeclaration */ || container.kind === 148 /* Constructor */) {
                var classNode = container.parent;
                getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
            }
            else {
                getNodeLinks(container).flags |= 4 /* CaptureThis */;
            }
        }
        function findFirstSuperCall(n) {
            if (ts.isSuperCallExpression(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 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 === 148 /* Constructor */) {
                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, 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 === 180 /* 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 /* ES6 */);
            }
            switch (container.kind) {
                case 225 /* 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 224 /* 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 148 /* Constructor */:
                    if (isInConstructorArgumentInitializer(node, container)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
                    }
                    break;
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                    if (container.flags & 32 /* Static */) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
                    }
                    break;
                case 140 /* 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) || getFunctionLikeThisParameter(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 === 179 /* FunctionExpression */ &&
                    ts.isInJavaScriptFile(container.parent) &&
                    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 type = getContextuallyTypedThisType(container);
                if (type) {
                    return type;
                }
                var thisType = getThisTypeOfDeclaration(container);
                if (thisType) {
                    return thisType;
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                var type = container.flags & 32 /* Static */ ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
                return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true, /*includeOuterFunctions*/ true);
            }
            if (ts.isInJavaScriptFile(node)) {
                var type = getTypeForThisExpressionFromJSDoc(container);
                if (type && type !== unknownType) {
                    return type;
                }
            }
            if (compilerOptions.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 typeTag = ts.getJSDocTypeTag(node);
            if (typeTag && typeTag.typeExpression && typeTag.typeExpression.type && typeTag.typeExpression.type.kind === 269 /* JSDocFunctionType */) {
                var jsDocFunctionType = typeTag.typeExpression.type;
                if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].type.kind === 272 /* JSDocThisType */) {
                    return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
                }
            }
        }
        function isInConstructorArgumentInitializer(node, constructorDecl) {
            for (var n = node; n && n !== constructorDecl; n = n.parent) {
                if (n.kind === 142 /* Parameter */) {
                    return true;
                }
            }
            return false;
        }
        function checkSuperExpression(node) {
            var isCallExpression = node.parent.kind === 174 /* CallExpression */ && node.parent.expression === node;
            var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true);
            var needToCaptureLexicalThis = false;
            if (!isCallExpression) {
                // adjust the container reference in case if super is used inside arrow functions with arbitrary deep nesting
                while (container && container.kind === 180 /* ArrowFunction */) {
                    container = ts.getSuperContainer(container, /*stopOnFunctions*/ true);
                    needToCaptureLexicalThis = languageVersion < 2 /* ES6 */;
                }
            }
            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 = node;
                while (current && current !== container && current.kind !== 140 /* ComputedPropertyName */) {
                    current = current.parent;
                }
                if (current && current.kind === 140 /* 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 === 171 /* 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 ((container.flags & 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 === 147 /* MethodDeclaration */ && container.flags & 256 /* Async */) {
                if (ts.isSuperPropertyOrElementAccess(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 === 171 /* ObjectLiteralExpression */) {
                if (languageVersion < 2 /* ES6 */) {
                    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 === 148 /* 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 === 148 /* 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 === 171 /* ObjectLiteralExpression */) {
                        if (container.flags & 32 /* Static */) {
                            return container.kind === 147 /* MethodDeclaration */ ||
                                container.kind === 146 /* MethodSignature */ ||
                                container.kind === 149 /* GetAccessor */ ||
                                container.kind === 150 /* SetAccessor */;
                        }
                        else {
                            return container.kind === 147 /* MethodDeclaration */ ||
                                container.kind === 146 /* MethodSignature */ ||
                                container.kind === 149 /* GetAccessor */ ||
                                container.kind === 150 /* SetAccessor */ ||
                                container.kind === 145 /* PropertyDeclaration */ ||
                                container.kind === 144 /* PropertySignature */ ||
                                container.kind === 148 /* Constructor */;
                        }
                    }
                }
                return false;
            }
        }
        function getContextuallyTypedThisType(func) {
            if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== 180 /* ArrowFunction */) {
                var contextualSignature = getContextualSignature(func);
                if (contextualSignature) {
                    return getThisTypeOfSignature(contextualSignature);
                }
            }
            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) {
                    var indexOfParameter = ts.indexOf(func.parameters, parameter);
                    if (iife.arguments && indexOfParameter < iife.arguments.length) {
                        if (parameter.dotDotDotToken) {
                            var restTypes = [];
                            for (var i = indexOfParameter; i < iife.arguments.length; i++) {
                                restTypes.push(getTypeOfExpression(iife.arguments[i]));
                            }
                            return createArrayType(getUnionType(restTypes));
                        }
                        var links = getNodeLinks(iife);
                        var cached = links.resolvedSignature;
                        links.resolvedSignature = anySignature;
                        var type = checkExpression(iife.arguments[indexOfParameter]);
                        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 (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) {
                if (declaration.type) {
                    return getTypeFromTypeNode(declaration.type);
                }
                if (declaration.kind === 142 /* Parameter */) {
                    var type = getContextuallyTypedParameterType(declaration);
                    if (type) {
                        return type;
                    }
                }
                if (ts.isBindingPattern(declaration.name)) {
                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true);
                }
                if (ts.isBindingPattern(declaration.parent)) {
                    var parentDeclaration = declaration.parent.parent;
                    var name_12 = declaration.propertyName || declaration.name;
                    if (ts.isVariableLike(parentDeclaration) &&
                        parentDeclaration.type &&
                        !ts.isBindingPattern(name_12)) {
                        var text = getTextOfPropertyName(name_12);
                        if (text) {
                            return getTypeOfPropertyOfType(getTypeFromTypeNode(parentDeclaration.type), text);
                        }
                    }
                }
            }
            return undefined;
        }
        function getContextualTypeForReturnExpression(node) {
            var func = ts.getContainingFunction(node);
            if (ts.isAsyncFunctionLike(func)) {
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    return getPromisedType(contextualReturnType);
                }
                return undefined;
            }
            if (func && !func.asteriskToken) {
                return getContextualReturnType(func);
            }
            return undefined;
        }
        function getContextualTypeForYieldOperand(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    return node.asteriskToken
                        ? contextualReturnType
                        : getElementTypeOfIterableIterator(contextualReturnType);
                }
            }
            return undefined;
        }
        function isInParameterInitializerBeforeContainingFunction(node) {
            while (node.parent && !ts.isFunctionLike(node.parent)) {
                if (node.parent.kind === 142 /* 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.type ||
                functionDecl.kind === 148 /* Constructor */ ||
                functionDecl.kind === 149 /* GetAccessor */ && ts.getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(functionDecl.symbol, 150 /* SetAccessor */))) {
                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) {
                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) {
                var signature = getResolvedOrAnySignature(callTarget);
                return getTypeAtPosition(signature, argIndex);
            }
            return undefined;
        }
        function getContextualTypeForSubstitutionExpression(template, substitutionExpression) {
            if (template.parent.kind === 176 /* TaggedTemplateExpression */) {
                return getContextualTypeForArgument(template.parent, substitutionExpression);
            }
            return undefined;
        }
        function getContextualTypeForBinaryOperand(node) {
            var binaryExpression = node.parent;
            var operator = binaryExpression.operatorToken.kind;
            if (operator >= 56 /* FirstAssignment */ && operator <= 68 /* LastAssignment */) {
                // In an assignment expression, the right operand is contextually typed by the type of the left operand.
                if (node === binaryExpression.right) {
                    return checkExpression(binaryExpression.left);
                }
            }
            else if (operator === 52 /* 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 = checkExpression(binaryExpression.left);
                }
                return type;
            }
            else if (operator === 51 /* AmpersandAmpersandToken */ || operator === 24 /* CommaToken */) {
                if (node === binaryExpression.right) {
                    return getContextualType(binaryExpression);
                }
            }
            return undefined;
        }
        // Apply a mapping function to a contextual type and return the resulting type. If the contextual type
        // is a union type, the mapping function is applied to each constituent type and a union of the resulting
        // types is returned.
        function applyToContextualType(type, mapper) {
            if (!(type.flags & 16384 /* Union */)) {
                return mapper(type);
            }
            var types = type.types;
            var mappedType;
            var mappedTypes;
            for (var _i = 0, types_8 = types; _i < types_8.length; _i++) {
                var current = types_8[_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 getTypeOfPropertyOfContextualType(type, name) {
            return applyToContextualType(type, function (t) {
                var prop = t.flags & 130048 /* StructuredType */ ? getPropertyOfType(t, name) : undefined;
                return prop ? getTypeOfSymbol(prop) : undefined;
            });
        }
        function getIndexTypeOfContextualType(type, kind) {
            return applyToContextualType(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 & 16384 /* 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 = getSymbolOfNode(element).name;
                    var propertyType = getTypeOfPropertyOfContextualType(type, symbolName);
                    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(node) {
            var arrayLiteral = node.parent;
            var type = getApparentTypeOfContextualType(arrayLiteral);
            if (type) {
                var index = ts.indexOf(arrayLiteral.elements, node);
                return getTypeOfPropertyOfContextualType(type, "" + index)
                    || getIndexTypeOfContextualType(type, 1 /* Number */)
                    || (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(type, /*errorNode*/ undefined) : undefined);
            }
            return undefined;
        }
        // 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 getContextualTypeForJsxAttribute(attribute) {
            var kind = attribute.kind;
            var jsxElement = attribute.parent;
            var attrsType = getJsxElementAttributesType(jsxElement);
            if (attribute.kind === 246 /* JsxAttribute */) {
                if (!attrsType || isTypeAny(attrsType)) {
                    return undefined;
                }
                return getTypeOfPropertyOfType(attrsType, attribute.name.text);
            }
            else if (attribute.kind === 247 /* JsxSpreadAttribute */) {
                return attrsType;
            }
            ts.Debug.fail("Expected JsxAttribute or JsxSpreadAttribute, got ts.SyntaxKind[" + kind + "]");
        }
        // 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 218 /* VariableDeclaration */:
                case 142 /* Parameter */:
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 169 /* BindingElement */:
                    return getContextualTypeForInitializerExpression(node);
                case 180 /* ArrowFunction */:
                case 211 /* ReturnStatement */:
                    return getContextualTypeForReturnExpression(node);
                case 190 /* YieldExpression */:
                    return getContextualTypeForYieldOperand(parent);
                case 174 /* CallExpression */:
                case 175 /* NewExpression */:
                    return getContextualTypeForArgument(parent, node);
                case 177 /* TypeAssertionExpression */:
                case 195 /* AsExpression */:
                    return getTypeFromTypeNode(parent.type);
                case 187 /* BinaryExpression */:
                    return getContextualTypeForBinaryOperand(node);
                case 253 /* PropertyAssignment */:
                    return getContextualTypeForObjectLiteralElement(parent);
                case 170 /* ArrayLiteralExpression */:
                    return getContextualTypeForElementExpression(node);
                case 188 /* ConditionalExpression */:
                    return getContextualTypeForConditionalOperand(node);
                case 197 /* TemplateSpan */:
                    ts.Debug.assert(parent.parent.kind === 189 /* TemplateExpression */);
                    return getContextualTypeForSubstitutionExpression(parent.parent, node);
                case 178 /* ParenthesizedExpression */:
                    return getContextualType(parent);
                case 248 /* JsxExpression */:
                    return getContextualType(parent);
                case 246 /* JsxAttribute */:
                case 247 /* JsxSpreadAttribute */:
                    return getContextualTypeForJsxAttribute(parent);
            }
            return undefined;
        }
        // If the given type is an object or union type, if that type has a single signature, and if
        // that signature is non-generic, return the signature. Otherwise return undefined.
        function getNonGenericSignature(type) {
            var signatures = getSignaturesOfStructuredType(type, 0 /* Call */);
            if (signatures.length === 1) {
                var signature = signatures[0];
                if (!signature.typeParameters) {
                    return signature;
                }
            }
        }
        function isFunctionExpressionOrArrowFunction(node) {
            return node.kind === 179 /* FunctionExpression */ || node.kind === 180 /* 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 !== 147 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var type = getContextualTypeForFunctionLikeDeclaration(node);
            if (!type) {
                return undefined;
            }
            if (!(type.flags & 16384 /* Union */)) {
                return getNonGenericSignature(type);
            }
            var signatureList;
            var types = type.types;
            for (var _i = 0, types_9 = types; _i < types_9.length; _i++) {
                var current = types_9[_i];
                var signature = getNonGenericSignature(current);
                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;
        }
        /**
         * Detect if the mapper implies an inference context. Specifically, there are 4 possible values
         * for a mapper. Let's go through each one of them:
         *
         *    1. undefined - this means we are not doing inferential typing, but we may do contextual typing,
         *       which could cause us to assign a parameter a type
         *    2. identityMapper - means we want to avoid assigning a parameter a type, whether or not we are in
         *       inferential typing (context is undefined for the identityMapper)
         *    3. a mapper created by createInferenceMapper - we are doing inferential typing, we want to assign
         *       types to parameters and fix type parameters (context is defined)
         *    4. an instantiation mapper created by createTypeMapper or createTypeEraser - this should never be
         *       passed as the contextual mapper when checking an expression (context is undefined for these)
         *
         * isInferentialContext is detecting if we are in case 3
         */
        function isInferentialContext(mapper) {
            return mapper && mapper.context;
        }
        function checkSpreadElementExpression(node, contextualMapper) {
            // It is usually not safe to call checkExpressionCached if we can be contextually typing.
            // You can tell that we are contextually typing because of the contextualMapper parameter.
            // While it is true that a spread element can have a contextual type, it does not do anything
            // with this type. It is neither affected by it, nor does it propagate it to its operand.
            // So the fact that contextualMapper is passed is not important, because the operand of a spread
            // element is not contextually typed.
            var arrayOrIterableType = checkExpressionCached(node.expression, contextualMapper);
            return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false);
        }
        function hasDefaultValue(node) {
            return (node.kind === 169 /* BindingElement */ && !!node.initializer) ||
                (node.kind === 187 /* BinaryExpression */ && node.operatorToken.kind === 56 /* EqualsToken */);
        }
        function checkArrayLiteral(node, contextualMapper) {
            var elements = node.elements;
            var hasSpreadElement = false;
            var elementTypes = [];
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                var e = elements_1[_i];
                if (inDestructuringPattern && e.kind === 191 /* SpreadElementExpression */) {
                    // 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, contextualMapper);
                    var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) ||
                        (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
                    if (restElementType) {
                        elementTypes.push(restElementType);
                    }
                }
                else {
                    var type = checkExpression(e, contextualMapper);
                    elementTypes.push(type);
                }
                hasSpreadElement = hasSpreadElement || e.kind === 191 /* SpreadElementExpression */;
            }
            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 = createNewTupleType(elementTypes);
                    type.pattern = node;
                    return type;
                }
                var contextualType = getApparentTypeOfContextualType(node);
                if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
                    var pattern = contextualType.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 === 168 /* ArrayBindingPattern */ || pattern.kind === 170 /* ArrayLiteralExpression */)) {
                        var patternElements = pattern.elements;
                        for (var i = elementTypes.length; i < patternElements.length; i++) {
                            var patternElement = patternElements[i];
                            if (hasDefaultValue(patternElement)) {
                                elementTypes.push(contextualType.elementTypes[i]);
                            }
                            else {
                                if (patternElement.kind !== 193 /* 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) : strictNullChecks ? neverType : undefinedWideningType);
        }
        function isNumericName(name) {
            return name.kind === 140 /* ComputedPropertyName */ ? isNumericComputedName(name) : isNumericLiteralName(name.text);
        }
        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 isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), 132 /* NumberLike */);
        }
        function isTypeAnyOrAllConstituentTypesHaveKind(type, kind) {
            return isTypeAny(type) || isTypeOfKind(type, kind);
        }
        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 (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, 132 /* NumberLike */ | 258 /* StringLike */ | 16777216 /* ESSymbol */)) {
                    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(node, properties, kind) {
            var propTypes = [];
            for (var i = 0; i < properties.length; i++) {
                if (kind === 0 /* String */ || isNumericName(node.properties[i].name)) {
                    propTypes.push(getTypeOfSymbol(properties[i]));
                }
            }
            var unionType = propTypes.length ? getUnionType(propTypes) : undefinedType;
            return createIndexInfo(unionType, /*isReadonly*/ false);
        }
        function checkObjectLiteral(node, contextualMapper) {
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            // Grammar checking
            checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
            var propertiesTable = {};
            var propertiesArray = [];
            var contextualType = getApparentTypeOfContextualType(node);
            var contextualTypeHasPattern = contextualType && contextualType.pattern &&
                (contextualType.pattern.kind === 167 /* ObjectBindingPattern */ || contextualType.pattern.kind === 171 /* ObjectLiteralExpression */);
            var typeFlags = 0;
            var patternWithComputedProperties = false;
            var hasComputedStringProperty = false;
            var hasComputedNumberProperty = false;
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var memberDecl = _a[_i];
                var member = memberDecl.symbol;
                if (memberDecl.kind === 253 /* PropertyAssignment */ ||
                    memberDecl.kind === 254 /* ShorthandPropertyAssignment */ ||
                    ts.isObjectLiteralMethod(memberDecl)) {
                    var type = void 0;
                    if (memberDecl.kind === 253 /* PropertyAssignment */) {
                        type = checkPropertyAssignment(memberDecl, contextualMapper);
                    }
                    else if (memberDecl.kind === 147 /* MethodDeclaration */) {
                        type = checkObjectLiteralMethod(memberDecl, contextualMapper);
                    }
                    else {
                        ts.Debug.assert(memberDecl.kind === 254 /* ShorthandPropertyAssignment */);
                        type = checkExpression(memberDecl.name, contextualMapper);
                    }
                    typeFlags |= type.flags;
                    var prop = createSymbol(4 /* Property */ | 67108864 /* Transient */ | member.flags, member.name);
                    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 === 253 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) ||
                            (memberDecl.kind === 254 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer);
                        if (isOptional) {
                            prop.flags |= 536870912 /* Optional */;
                        }
                        if (ts.hasDynamicName(memberDecl)) {
                            patternWithComputedProperties = true;
                        }
                    }
                    else if (contextualTypeHasPattern && !(contextualType.flags & 67108864 /* 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.name);
                        if (impliedProp) {
                            prop.flags |= impliedProp.flags & 536870912 /* Optional */;
                        }
                        else if (!compilerOptions.suppressExcessPropertyErrors) {
                            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 {
                    // 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 === 149 /* GetAccessor */ || memberDecl.kind === 150 /* SetAccessor */);
                    checkAccessorDeclaration(memberDecl);
                }
                if (ts.hasDynamicName(memberDecl)) {
                    if (isNumericName(memberDecl.name)) {
                        hasComputedNumberProperty = true;
                    }
                    else {
                        hasComputedStringProperty = true;
                    }
                }
                else {
                    propertiesTable[member.name] = 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 _b = 0, _c = getPropertiesOfType(contextualType); _b < _c.length; _b++) {
                    var prop = _c[_b];
                    if (!ts.hasProperty(propertiesTable, prop.name)) {
                        if (!(prop.flags & 536870912 /* 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[prop.name] = prop;
                        propertiesArray.push(prop);
                    }
                }
            }
            var stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, propertiesArray, 0 /* String */) : undefined;
            var numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, 1 /* Number */) : undefined;
            var result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
            var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 1048576 /* FreshObjectLiteral */;
            result.flags |= 524288 /* ObjectLiteral */ | 4194304 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 14680064 /* PropagatingFlags */) | (patternWithComputedProperties ? 67108864 /* ObjectLiteralPatternWithComputedProperties */ : 0);
            if (inDestructuringPattern) {
                result.pattern = node;
            }
            return result;
        }
        function checkJsxSelfClosingElement(node) {
            checkJsxOpeningLikeElement(node);
            return jsxElementType || 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);
            }
            // Check children
            for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
                var child = _a[_i];
                switch (child.kind) {
                    case 248 /* JsxExpression */:
                        checkJsxExpression(child);
                        break;
                    case 241 /* JsxElement */:
                        checkJsxElement(child);
                        break;
                    case 242 /* JsxSelfClosingElement */:
                        checkJsxSelfClosingElement(child);
                        break;
                }
            }
            return jsxElementType || 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 name.indexOf("-") < 0;
        }
        /**
         * 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
            if (tagName.kind === 172 /* PropertyAccessExpression */ || tagName.kind === 97 /* ThisKeyword */) {
                return false;
            }
            else {
                return ts.isIntrinsicJsxName(tagName.text);
            }
        }
        function checkJsxAttribute(node, elementAttributesType, nameTable) {
            var correspondingPropType = undefined;
            // Look up the corresponding property for this attribute
            if (elementAttributesType === emptyObjectType && isUnhyphenatedJsxName(node.name.text)) {
                // If there is no 'props' property, you may not have non-"data-" attributes
                error(node.parent, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName());
            }
            else if (elementAttributesType && !isTypeAny(elementAttributesType)) {
                var correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text);
                correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol);
                if (isUnhyphenatedJsxName(node.name.text)) {
                    // Maybe there's a string indexer?
                    var indexerType = getIndexTypeOfType(elementAttributesType, 0 /* String */);
                    if (indexerType) {
                        correspondingPropType = indexerType;
                    }
                    else {
                        // If there's no corresponding property with this name, error
                        if (!correspondingPropType) {
                            error(node.name, ts.Diagnostics.Property_0_does_not_exist_on_type_1, node.name.text, typeToString(elementAttributesType));
                            return unknownType;
                        }
                    }
                }
            }
            var exprType;
            if (node.initializer) {
                exprType = checkExpression(node.initializer);
            }
            else {
                // <Elem attr /> is sugar for <Elem attr={true} />
                exprType = booleanType;
            }
            if (correspondingPropType) {
                checkTypeAssignableTo(exprType, correspondingPropType, node);
            }
            nameTable[node.name.text] = true;
            return exprType;
        }
        function checkJsxSpreadAttribute(node, elementAttributesType, nameTable) {
            var type = checkExpression(node.expression);
            var props = getPropertiesOfType(type);
            for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
                var prop = props_2[_i];
                // Is there a corresponding property in the element attributes type? Skip checking of properties
                // that have already been assigned to, as these are not actually pushed into the resulting type
                if (!nameTable[prop.name]) {
                    var targetPropSym = getPropertyOfType(elementAttributesType, prop.name);
                    if (targetPropSym) {
                        var msg = ts.chainDiagnosticMessages(undefined, ts.Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name);
                        checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(targetPropSym), node, undefined, msg);
                    }
                    nameTable[prop.name] = true;
                }
            }
            return type;
        }
        function getJsxType(name) {
            if (jsxTypes[name] === undefined) {
                return jsxTypes[name] = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType;
            }
            return jsxTypes[name];
        }
        /**
          * 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
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.text);
                    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, node.tagName.text, "JSX." + JsxNames.IntrinsicElements);
                    return links.resolvedSymbol = unknownSymbol;
                }
                else {
                    if (compilerOptions.noImplicitAny) {
                        error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, 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 & 16384 /* 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;
                }
            }
            return getUnionType(signatures.map(getReturnTypeOfSignature));
        }
        /// 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() {
            // JSX
            var jsxNamespace = getGlobalSymbol(JsxNames.JSX, 1536 /* Namespace */, /*diagnosticMessage*/ undefined);
            // JSX.ElementAttributesProperty [symbol]
            var attribsPropTypeSym = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.ElementAttributesPropertyNameContainer, 793056 /* Type */);
            // JSX.ElementAttributesProperty [type]
            var attribPropType = attribsPropTypeSym && getDeclaredTypeOfSymbol(attribsPropTypeSym);
            // The properties of JSX.ElementAttributesProperty
            var attribProperties = attribPropType && getPropertiesOfType(attribPropType);
            if (attribProperties) {
                // Element Attributes has zero properties, so the element attributes type will be the class instance type
                if (attribProperties.length === 0) {
                    return "";
                }
                else if (attribProperties.length === 1) {
                    return attribProperties[0].name;
                }
                else {
                    error(attribsPropTypeSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, JsxNames.ElementAttributesPropertyNameContainer);
                    return undefined;
                }
            }
            else {
                // No interface exists, so the element attributes type will be an implicit any
                return undefined;
            }
        }
        /**
         * Given React element instance type and the class type, resolve the Jsx type
         * Pass elemType to handle individual type in the union typed element type.
         */
        function getResolvedJsxType(node, elemType, elemClassType) {
            if (!elemType) {
                elemType = checkExpression(node.tagName);
            }
            if (elemType.flags & 16384 /* Union */) {
                var types = elemType.types;
                return getUnionType(types.map(function (type) {
                    return getResolvedJsxType(node, type, elemClassType);
                }));
            }
            // 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 (elemType.flags & 2 /* String */) {
                return anyType;
            }
            else if (elemType.flags & 256 /* 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
                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
                if (intrinsicElementsType !== unknownType) {
                    var stringLiteralTypeName = elemType.text;
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, stringLiteralTypeName);
                    if (intrinsicProp) {
                        return getTypeOfSymbol(intrinsicProp);
                    }
                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                    if (indexSignatureType) {
                        return indexSignatureType;
                    }
                    error(node, 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(node, elemType);
            if (!elemClassType || !isTypeAssignableTo(elemInstanceType, elemClassType)) {
                // Is this is a stateless function component? See if its single signature's return type is
                // assignable to the JSX Element Type
                if (jsxElementType) {
                    var callSignatures = elemType && getSignaturesOfType(elemType, 0 /* Call */);
                    var callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0];
                    var callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
                    var paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0]));
                    if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) {
                        // Intersect in JSX.IntrinsicAttributes if it exists
                        var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
                        if (intrinsicAttributes !== unknownType) {
                            paramType = intersectTypes(intrinsicAttributes, paramType);
                        }
                        return paramType;
                    }
                }
            }
            // Issue an error if this return type isn't assignable to JSX.ElementClass
            if (elemClassType) {
                checkTypeRelatedTo(elemInstanceType, elemClassType, assignableRelation, node, 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 if (attributesType.flags & 16384 /* Union */) {
                    // Props cannot be a union type
                    error(node.tagName, ts.Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType));
                    return anyType;
                }
                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;
                }
            }
        }
        /**
         * Given an opening/self-closing element, get the 'element attributes type', i.e. the type that tells
         * us which attributes are valid on a given element.
         */
        function getJsxElementAttributesType(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedJsxType) {
                if (isJsxIntrinsicIdentifier(node.tagName)) {
                    var symbol = getIntrinsicTagSymbol(node);
                    if (links.jsxFlags & 1 /* IntrinsicNamedElement */) {
                        return links.resolvedJsxType = getTypeOfSymbol(symbol);
                    }
                    else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) {
                        return links.resolvedJsxType = getIndexInfoOfSymbol(symbol, 0 /* String */).type;
                    }
                    else {
                        return links.resolvedJsxType = unknownType;
                    }
                }
                else {
                    var elemClassType = getJsxGlobalElementClassType();
                    return links.resolvedJsxType = getResolvedJsxType(node, undefined, elemClassType);
                }
            }
            return links.resolvedJsxType;
        }
        /**
         * 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 = getJsxElementAttributesType(attrib.parent);
            var prop = getPropertyOfType(attributesType, attrib.name.text);
            return prop || unknownSymbol;
        }
        function getJsxGlobalElementClassType() {
            if (!jsxElementClassType) {
                jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
            }
            return jsxElementClassType;
        }
        /// Returns all the properties of the Jsx.IntrinsicElements interface
        function getJsxIntrinsicTagNames() {
            var intrinsics = getJsxType(JsxNames.IntrinsicElements);
            return intrinsics ? getPropertiesOfType(intrinsics) : 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 (jsxElementType === undefined) {
                if (compilerOptions.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 symbol should be marked as 'used' so we don't incorrectly elide its import. And if there
            // is no reactNamespace symbol in scope when targeting React emit, we should issue an error.
            var reactRefErr = compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined;
            var reactNamespace = compilerOptions.reactNamespace ? compilerOptions.reactNamespace : "React";
            var reactSym = resolveName(node.tagName, reactNamespace, 107455 /* Value */, reactRefErr, reactNamespace);
            if (reactSym) {
                getSymbolLinks(reactSym).referenced = true;
            }
            var targetAttributesType = getJsxElementAttributesType(node);
            var nameTable = {};
            // Process this array in right-to-left order so we know which
            // attributes (mostly from spreads) are being overwritten and
            // thus should have their types ignored
            var sawSpreadedAny = false;
            for (var i = node.attributes.length - 1; i >= 0; i--) {
                if (node.attributes[i].kind === 246 /* JsxAttribute */) {
                    checkJsxAttribute((node.attributes[i]), targetAttributesType, nameTable);
                }
                else {
                    ts.Debug.assert(node.attributes[i].kind === 247 /* JsxSpreadAttribute */);
                    var spreadType = checkJsxSpreadAttribute((node.attributes[i]), targetAttributesType, nameTable);
                    if (isTypeAny(spreadType)) {
                        sawSpreadedAny = true;
                    }
                }
            }
            // Check that all required properties have been provided. If an 'any'
            // was spreaded in, though, assume that it provided all required properties
            if (targetAttributesType && !sawSpreadedAny) {
                var targetProperties = getPropertiesOfType(targetAttributesType);
                for (var i = 0; i < targetProperties.length; i++) {
                    if (!(targetProperties[i].flags & 536870912 /* Optional */) &&
                        nameTable[targetProperties[i].name] === undefined) {
                        error(node, ts.Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType));
                    }
                }
            }
        }
        function checkJsxExpression(node) {
            if (node.expression) {
                return checkExpression(node.expression);
            }
            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 : 145 /* PropertyDeclaration */;
        }
        function getDeclarationFlagsFromSymbol(s) {
            return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : s.flags & 134217728 /* Prototype */ ? 4 /* Public */ | 32 /* Static */ : 0;
        }
        /**
         * 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 checkClassPropertyAccess(node, left, type, prop) {
            var flags = getDeclarationFlagsFromSymbol(prop);
            var declaringClass = getDeclaredTypeOfSymbol(getParentOfSymbol(prop));
            var errorNode = node.kind === 172 /* PropertyAccessExpression */ || node.kind === 218 /* VariableDeclaration */ ?
                node.name :
                node.right;
            if (left.kind === 95 /* 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 /* ES6 */ && getDeclarationKindFromSymbol(prop) !== 147 /* MethodDeclaration */) {
                    // `prop` refers to a *property* declared in the super class
                    // rather than a *method*, so it does not satisfy the above criteria.
                    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(declaringClass));
                    return false;
                }
            }
            // Public properties are otherwise accessible.
            if (!(flags & (8 /* Private */ | 16 /* Protected */))) {
                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(declaringClass));
                    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 === 95 /* SuperKeyword */) {
                return true;
            }
            // Get the enclosing class that has the declaring class as its base type
            var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
                var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
                return hasBaseType(enclosingClass, declaringClass) ? 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(declaringClass));
                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 & 33554432 /* ThisType */) {
                // get the original type -- represented as the type constraint of the 'this' type
                type = getConstraintOfTypeParameter(type);
            }
            // TODO: why is the first part of this check here?
            if (!(getTargetType(type).flags & (1024 /* Class */ | 2048 /* Interface */) && 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) {
            var type = checkExpression(node);
            if (strictNullChecks) {
                var kind = getCombinedTypeFlags(type) & 96 /* Nullable */;
                if (kind) {
                    error(node, kind & 32 /* Undefined */ ? kind & 64 /* Null */ ?
                        ts.Diagnostics.Object_is_possibly_null_or_undefined :
                        ts.Diagnostics.Object_is_possibly_undefined :
                        ts.Diagnostics.Object_is_possibly_null);
                }
                return getNonNullableType(type);
            }
            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)) {
                return type;
            }
            var apparentType = getApparentType(getWidenedType(type));
            if (apparentType === unknownType || (type.flags & 512 /* TypeParameter */ && isTypeAny(apparentType))) {
                // handle cases when type is Type parameter with invalid or any constraint
                return apparentType;
            }
            var prop = getPropertyOfType(apparentType, right.text);
            if (!prop) {
                if (right.text && !checkAndReportErrorForExtendingInterface(node)) {
                    error(right, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(right), typeToString(type.flags & 33554432 /* ThisType */ ? apparentType : type));
                }
                return unknownType;
            }
            if (noUnusedIdentifiers &&
                (prop.flags & 106500 /* ClassMember */) &&
                prop.valueDeclaration && (prop.valueDeclaration.flags & 8 /* Private */)) {
                if (prop.flags & 16777216 /* Instantiated */) {
                    getSymbolLinks(prop).target.isReferenced = true;
                }
                else {
                    prop.isReferenced = true;
                }
            }
            getNodeLinks(node).resolvedSymbol = prop;
            if (prop.parent && prop.parent.flags & 32 /* Class */) {
                checkClassPropertyAccess(node, left, apparentType, prop);
            }
            var propType = getTypeOfSymbol(prop);
            // 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 !== 172 /* PropertyAccessExpression */ || ts.isAssignmentTarget(node) ||
                !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) &&
                    !(prop.flags & 8192 /* Method */ && propType.flags & 16384 /* Union */)) {
                return propType;
            }
            return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true, /*includeOuterFunctions*/ false);
        }
        function isValidPropertyAccess(node, propertyName) {
            var left = node.kind === 172 /* PropertyAccessExpression */
                ? node.expression
                : node.left;
            var type = checkExpression(left);
            if (type !== unknownType && !isTypeAny(type)) {
                var prop = getPropertyOfType(getWidenedType(type), propertyName);
                if (prop && prop.parent && prop.parent.flags & 32 /* Class */) {
                    return checkClassPropertyAccess(node, left, type, prop);
                }
            }
            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 === 219 /* VariableDeclarationList */) {
                var variable = initializer.declarations[0];
                if (variable && !ts.isBindingPattern(variable.name)) {
                    return getSymbolOfNode(variable);
                }
            }
            else if (initializer.kind === 69 /* 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 = skipParenthesizedNodes(expr);
            if (e.kind === 69 /* Identifier */) {
                var symbol = getResolvedSymbol(e);
                if (symbol.flags & 3 /* Variable */) {
                    var child = expr;
                    var node = expr.parent;
                    while (node) {
                        if (node.kind === 207 /* ForInStatement */ &&
                            child === node.statement &&
                            getForInVariableSymbol(node) === symbol &&
                            hasNumericPropertyNames(checkExpression(node.expression))) {
                            return true;
                        }
                        child = node;
                        node = node.parent;
                    }
                }
            }
            return false;
        }
        function checkIndexedAccess(node) {
            // Grammar checking
            if (!node.argumentExpression) {
                var sourceFile = ts.getSourceFileOfNode(node);
                if (node.parent.kind === 175 /* 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);
                }
            }
            // Obtain base constraint such that we can bail out if the constraint is an unknown type
            var objectType = getApparentType(checkNonNullExpression(node.expression));
            var indexType = node.argumentExpression ? checkExpression(node.argumentExpression) : unknownType;
            if (objectType === unknownType) {
                return unknownType;
            }
            var isConstEnum = isConstEnumObjectType(objectType);
            if (isConstEnum &&
                (!node.argumentExpression || node.argumentExpression.kind !== 9 /* StringLiteral */)) {
                error(node.argumentExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
                return unknownType;
            }
            // TypeScript 1.0 spec (April 2014): 4.10 Property Access
            // - If IndexExpr is a string literal or a numeric literal and ObjExpr's apparent type has a property with the name
            //    given by that literal(converted to its string representation in the case of a numeric literal), the property access is of the type of that property.
            // - Otherwise, if ObjExpr's apparent type has a numeric index signature and IndexExpr is of type Any, the Number primitive type, or an enum type,
            //    the property access is of the type of that index signature.
            // - Otherwise, if ObjExpr's apparent type has a string index signature and IndexExpr is of type Any, the String or Number primitive type, or an enum type,
            //    the property access is of the type of that index signature.
            // - Otherwise, if IndexExpr is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any.
            // See if we can index as a property.
            if (node.argumentExpression) {
                var name_13 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType);
                if (name_13 !== undefined) {
                    var prop = getPropertyOfType(objectType, name_13);
                    if (prop) {
                        getNodeLinks(node).resolvedSymbol = prop;
                        return getTypeOfSymbol(prop);
                    }
                    else if (isConstEnum) {
                        error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_13, symbolToString(objectType.symbol));
                        return unknownType;
                    }
                }
            }
            // Check for compatible indexer types.
            if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 258 /* StringLike */ | 132 /* NumberLike */ | 16777216 /* ESSymbol */)) {
                // Try to use a number indexer.
                if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, 132 /* NumberLike */) || isForInVariableForNumericPropertyNames(node.argumentExpression)) {
                    var numberIndexInfo = getIndexInfoOfType(objectType, 1 /* Number */);
                    if (numberIndexInfo) {
                        getNodeLinks(node).resolvedIndexInfo = numberIndexInfo;
                        return numberIndexInfo.type;
                    }
                }
                // Try to use string indexing.
                var stringIndexInfo = getIndexInfoOfType(objectType, 0 /* String */);
                if (stringIndexInfo) {
                    getNodeLinks(node).resolvedIndexInfo = stringIndexInfo;
                    return stringIndexInfo.type;
                }
                // Fall back to any.
                if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !isTypeAny(objectType)) {
                    error(node, getIndexTypeOfType(objectType, 1 /* Number */) ?
                        ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number :
                        ts.Diagnostics.Index_signature_of_object_type_implicitly_has_an_any_type);
                }
                return anyType;
            }
            // REVIEW: Users should know the type that was actually used.
            error(node, ts.Diagnostics.An_index_expression_argument_must_be_of_type_string_number_symbol_or_any);
            return unknownType;
        }
        /**
         * If indexArgumentExpression is a string literal or number literal, returns its text.
         * If indexArgumentExpression is a constant value, returns its string value.
         * If indexArgumentExpression is a well known symbol, returns the property name corresponding
         *    to this symbol, as long as it is a proper symbol reference.
         * Otherwise, returns undefined.
         */
        function getPropertyNameForIndexedAccess(indexArgumentExpression, indexArgumentType) {
            if (indexArgumentExpression.kind === 9 /* StringLiteral */ || indexArgumentExpression.kind === 8 /* NumericLiteral */) {
                return indexArgumentExpression.text;
            }
            if (indexArgumentExpression.kind === 173 /* ElementAccessExpression */ || indexArgumentExpression.kind === 172 /* PropertyAccessExpression */) {
                var value = getConstantValue(indexArgumentExpression);
                if (value !== undefined) {
                    return value.toString();
                }
            }
            if (checkThatExpressionIsProperSymbolReference(indexArgumentExpression, indexArgumentType, /*reportError*/ false)) {
                var rightHandSideName = indexArgumentExpression.name.text;
                return ts.getPropertyNameForKnownSymbolName(rightHandSideName);
            }
            return undefined;
        }
        /**
         * A proper symbol reference requires the following:
         *   1. The property access denotes a property that exists
         *   2. The expression is of the form Symbol.<identifier>
         *   3. The property access is of the primitive type symbol.
         *   4. Symbol in this context resolves to the global Symbol object
         */
        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 & 16777216 /* 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();
            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 resolveUntypedCall(node) {
            if (node.kind === 176 /* TaggedTemplateExpression */) {
                checkExpression(node.template);
            }
            else if (node.kind !== 143 /* 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_2 = signatures; _i < signatures_2.length; _i++) {
                var signature = signatures_2[_i];
                var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
                var parent_9 = signature.declaration && signature.declaration.parent;
                if (!lastSymbol || symbol === lastSymbol) {
                    if (lastParent && parent_9 === lastParent) {
                        index++;
                    }
                    else {
                        lastParent = parent_9;
                        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_9;
                }
                lastSymbol = symbol;
                // specialized signatures always need to be placed before non-specialized signatures regardless
                // of the cutoff position; see GH#1133
                if (signature.hasStringLiterals) {
                    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 === 191 /* SpreadElementExpression */) {
                    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 isDecorator;
            var spreadArgIndex = -1;
            if (node.kind === 176 /* 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 === 189 /* 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 === 11 /* NoSubstitutionTemplateLiteral */);
                    callIsIncomplete = !!templateLiteral.isUnterminated;
                }
            }
            else if (node.kind === 143 /* Decorator */) {
                isDecorator = true;
                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 === 175 /* NewExpression */);
                    return signature.minArgumentCount === 0;
                }
                argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
                // If we are missing the close paren, 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 hasRightNumberOfTypeArgs = !typeArguments ||
                (signature.typeParameters && typeArguments.length === signature.typeParameters.length);
            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);
            }
            // 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 & 80896 /* ObjectType */) {
                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) {
            var context = createInferenceContext(signature.typeParameters, /*inferUnionTypes*/ true);
            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, instantiateType(source, contextualMapper), target);
            });
            return getSignatureInstantiation(signature, getInferredTypes(context));
        }
        function inferTypeArguments(node, signature, args, excludeArgument, context) {
            var typeParameters = signature.typeParameters;
            var inferenceMapper = getInferenceMapper(context);
            // Clear out all the inference results from the last time inferTypeArguments was called on this context
            for (var i = 0; i < typeParameters.length; 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 (!context.inferences[i].isFixed) {
                    context.inferredTypes[i] = undefined;
                }
            }
            // On this call to inferTypeArguments, we may get more inferences for certain type parameters that were not
            // fixed last time. This means that a type parameter that failed inference last time may succeed this time,
            // or vice versa. Therefore, the failedTypeParameterIndex is useless if it points to an unfixed type parameter,
            // because it may change. So here we reset it. However, getInferredType will not revisit any type parameters
            // that were previously fixed. So if a fixed type parameter failed previously, it will fail again because
            // it will contain the exact same set of inferences. So if we reset the index from a fixed type parameter,
            // we will lose information that we won't recover this time around.
            if (context.failedTypeParameterIndex !== undefined && !context.inferences[context.failedTypeParameterIndex].isFixed) {
                context.failedTypeParameterIndex = undefined;
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType) {
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                inferTypes(context, 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 !== 193 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = getEffectiveArgumentType(node, i, arg);
                    // 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 : inferenceMapper;
                        argType = checkExpressionWithContextualType(arg, paramType, mapper);
                    }
                    inferTypes(context, 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, checkExpressionWithContextualType(arg, paramType, inferenceMapper), paramType);
                    }
                }
            }
            getInferredTypes(context);
        }
        function checkTypeArguments(signature, typeArgumentNodes, typeArgumentTypes, reportErrors, headMessage) {
            var typeParameters = signature.typeParameters;
            var typeArgumentsAreAssignable = true;
            var mapper;
            for (var i = 0; i < typeParameters.length; i++) {
                if (typeArgumentsAreAssignable /* so far */) {
                    var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                    if (constraint) {
                        var errorInfo = void 0;
                        var typeArgumentHeadMessage = ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
                        if (reportErrors && headMessage) {
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, typeArgumentHeadMessage);
                            typeArgumentHeadMessage = headMessage;
                        }
                        if (!mapper) {
                            mapper = createTypeMapper(typeParameters, typeArgumentTypes);
                        }
                        var typeArgument = typeArgumentTypes[i];
                        typeArgumentsAreAssignable = checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo);
                    }
                }
            }
            return typeArgumentsAreAssignable;
        }
        function checkApplicableSignature(node, args, signature, relation, excludeArgument, reportErrors) {
            var thisType = getThisTypeOfSignature(signature);
            if (thisType && thisType !== voidType && node.kind !== 175 /* 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 !== 193 /* OmittedExpression */) {
                    // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = getEffectiveArgumentType(node, i, arg);
                    // 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) {
                        argType = arg.kind === 9 /* StringLiteral */ && !reportErrors
                            ? getStringLiteralTypeForText(arg.text)
                            : checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
                    }
                    // Use argument expression as error location when reporting errors
                    var errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined;
                    if (!checkTypeRelatedTo(argType, 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 === 174 /* CallExpression */) {
                var callee = node.expression;
                if (callee.kind === 172 /* PropertyAccessExpression */) {
                    return callee.expression;
                }
                else if (callee.kind === 173 /* 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) {
            var args;
            if (node.kind === 176 /* TaggedTemplateExpression */) {
                var template = node.template;
                args = [undefined];
                if (template.kind === 189 /* TemplateExpression */) {
                    ts.forEach(template.templateSpans, function (span) {
                        args.push(span.expression);
                    });
                }
            }
            else if (node.kind === 143 /* 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 {
                args = node.arguments || emptyArray;
            }
            return args;
        }
        /**
          * 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 === 143 /* Decorator */) {
                switch (node.parent.kind) {
                    case 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                        // A class decorator will have one argument (see `ClassDecorator` in core.d.ts)
                        return 1;
                    case 145 /* PropertyDeclaration */:
                        // A property declaration decorator will have two arguments (see
                        // `PropertyDecorator` in core.d.ts)
                        return 2;
                    case 147 /* MethodDeclaration */:
                    case 149 /* GetAccessor */:
                    case 150 /* 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 142 /* 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 === 221 /* 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 === 142 /* Parameter */) {
                // For a parameter decorator, the `target` is the parent type of the
                // parameter's containing method.
                node = node.parent;
                if (node.kind === 148 /* Constructor */) {
                    var classSymbol = getSymbolOfNode(node);
                    return getTypeOfSymbol(classSymbol);
                }
            }
            if (node.kind === 145 /* PropertyDeclaration */ ||
                node.kind === 147 /* MethodDeclaration */ ||
                node.kind === 149 /* GetAccessor */ ||
                node.kind === 150 /* 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 === 221 /* ClassDeclaration */) {
                ts.Debug.fail("Class decorators should not have a second synthetic argument.");
                return unknownType;
            }
            if (node.kind === 142 /* Parameter */) {
                node = node.parent;
                if (node.kind === 148 /* Constructor */) {
                    // For a constructor parameter decorator, the `propertyKey` will be `undefined`.
                    return anyType;
                }
            }
            if (node.kind === 145 /* PropertyDeclaration */ ||
                node.kind === 147 /* MethodDeclaration */ ||
                node.kind === 149 /* GetAccessor */ ||
                node.kind === 150 /* 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 69 /* Identifier */:
                    case 8 /* NumericLiteral */:
                    case 9 /* StringLiteral */:
                        return getStringLiteralTypeForText(element.name.text);
                    case 140 /* ComputedPropertyName */:
                        var nameType = checkComputedPropertyName(element.name);
                        if (isTypeOfKind(nameType, 16777216 /* 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 === 221 /* ClassDeclaration */) {
                ts.Debug.fail("Class decorators should not have a third synthetic argument.");
                return unknownType;
            }
            if (node.kind === 142 /* Parameter */) {
                // The `parameterIndex` for a parameter decorator is always a number
                return numberType;
            }
            if (node.kind === 145 /* PropertyDeclaration */) {
                ts.Debug.fail("Property decorators should not have a third synthetic argument.");
                return unknownType;
            }
            if (node.kind === 147 /* MethodDeclaration */ ||
                node.kind === 149 /* GetAccessor */ ||
                node.kind === 150 /* 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, arg) {
            // 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 === 143 /* Decorator */) {
                return getEffectiveDecoratorArgumentType(node, argIndex);
            }
            else if (argIndex === 0 && node.kind === 176 /* 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 === 143 /* Decorator */ ||
                (argIndex === 0 && node.kind === 176 /* 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 === 143 /* Decorator */) {
                // For a decorator, we use the expression of the decorator for error reporting.
                return node.expression;
            }
            else if (argIndex === 0 && node.kind === 176 /* 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, headMessage) {
            var isTaggedTemplate = node.kind === 176 /* TaggedTemplateExpression */;
            var isDecorator = node.kind === 143 /* Decorator */;
            var typeArguments;
            if (!isTaggedTemplate && !isDecorator) {
                typeArguments = node.typeArguments;
                // We already perform checking on the type arguments on the class declaration itself.
                if (node.expression.kind !== 95 /* SuperKeyword */) {
                    ts.forEach(typeArguments, checkSourceElement);
                }
            }
            var candidates = candidatesOutArray || [];
            // reorderCandidates fills up the candidates array directly
            reorderCandidates(signatures, candidates);
            if (!candidates.length) {
                reportError(ts.Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
                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 excludeArgument;
            if (!isDecorator) {
                // 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;
                    }
                }
            }
            // 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) {}
            //     function foo(n: number) {} // Report argument error on this overload
            //     function foo() {}
            //     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>(x: T, y: T) {} // Report type argument inference error
            //     function foo() {}
            //     foo(0, true);
            //
            var candidateForArgumentError;
            var candidateForTypeArgumentError;
            var resultOfFailedInference;
            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 === 174 /* 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) {
                // Reinitialize these pointers for round two
                candidateForArgumentError = undefined;
                candidateForTypeArgumentError = undefined;
                resultOfFailedInference = undefined;
                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) {
                // 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) {
                if (!isTaggedTemplate && !isDecorator && typeArguments) {
                    var typeArguments_2 = node.typeArguments;
                    checkTypeArguments(candidateForTypeArgumentError, typeArguments_2, ts.map(typeArguments_2, getTypeFromTypeNode), /*reportErrors*/ true, headMessage);
                }
                else {
                    ts.Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0);
                    var failedTypeParameter = candidateForTypeArgumentError.typeParameters[resultOfFailedInference.failedTypeParameterIndex];
                    var inferenceCandidates = getInferenceCandidates(resultOfFailedInference, resultOfFailedInference.failedTypeParameterIndex);
                    var diagnosticChainHead = ts.chainDiagnosticMessages(/*details*/ undefined, // details will be provided by call to reportNoCommonSupertypeError
                    ts.Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly, typeToString(failedTypeParameter));
                    if (headMessage) {
                        diagnosticChainHead = ts.chainDiagnosticMessages(diagnosticChainHead, headMessage);
                    }
                    reportNoCommonSupertypeError(inferenceCandidates, node.expression || node.tag, diagnosticChainHead);
                }
            }
            else {
                reportError(ts.Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
            }
            // 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 that anySignature.
            // Pick the first candidate that matches the arity. This way we can get a contextual type for cases like:
            //  declare function f(a: { xa: number; xb: number; });
            //  f({ |
            if (!produceDiagnostics) {
                for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
                    var candidate = candidates_1[_i];
                    if (hasCorrectArity(node, args, candidate)) {
                        if (candidate.typeParameters && typeArguments) {
                            candidate = getSignatureInstantiation(candidate, ts.map(typeArguments, getTypeFromTypeNode));
                        }
                        return candidate;
                    }
                }
            }
            return resolveErrorCall(node);
            function reportError(message, arg0, arg1, arg2) {
                var errorInfo;
                errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2);
                if (headMessage) {
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage);
                }
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, errorInfo));
            }
            function chooseOverload(candidates, relation, signatureHelpTrailingComma) {
                if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
                for (var _i = 0, candidates_2 = candidates; _i < candidates_2.length; _i++) {
                    var originalCandidate = candidates_2[_i];
                    if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) {
                        continue;
                    }
                    var candidate = void 0;
                    var typeArgumentsAreValid = void 0;
                    var inferenceContext = originalCandidate.typeParameters
                        ? createInferenceContext(originalCandidate.typeParameters, /*inferUnionTypes*/ false)
                        : undefined;
                    while (true) {
                        candidate = originalCandidate;
                        if (candidate.typeParameters) {
                            var typeArgumentTypes = void 0;
                            if (typeArguments) {
                                typeArgumentTypes = ts.map(typeArguments, getTypeFromTypeNode);
                                typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false);
                            }
                            else {
                                inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
                                typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined;
                                typeArgumentTypes = inferenceContext.inferredTypes;
                            }
                            if (!typeArgumentsAreValid) {
                                break;
                            }
                            candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
                        }
                        if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
                            break;
                        }
                        var index = excludeArgument ? ts.indexOf(excludeArgument, true) : -1;
                        if (index < 0) {
                            return candidate;
                        }
                        excludeArgument[index] = false;
                    }
                    // A post-mortem of this iteration of the loop. The signature was not applicable,
                    // so we want to track it as a candidate for reporting an error. If the candidate
                    // had no type parameters, or had no issues related to type arguments, we can
                    // report an error based on the arguments. If there was an issue with type
                    // arguments, then we can only report an error based on the type arguments.
                    if (originalCandidate.typeParameters) {
                        var instantiatedCandidate = candidate;
                        if (typeArgumentsAreValid) {
                            candidateForArgumentError = instantiatedCandidate;
                        }
                        else {
                            candidateForTypeArgumentError = originalCandidate;
                            if (!typeArguments) {
                                resultOfFailedInference = inferenceContext;
                            }
                        }
                    }
                    else {
                        ts.Debug.assert(originalCandidate === candidate);
                        candidateForArgumentError = originalCandidate;
                    }
                }
                return undefined;
            }
        }
        function resolveCallExpression(node, candidatesOutArray) {
            if (node.expression.kind === 95 /* 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);
                        return resolveCall(node, baseConstructors, candidatesOutArray);
                    }
                }
                return resolveUntypedCall(node);
            }
            var funcType = checkNonNullExpression(node.expression);
            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
            // 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. 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.
            // We exclude union types because we may have a union of function types that happen to have
            // no common signatures.
            if (isTypeAny(funcType) ||
                (isTypeAny(apparentType) && funcType.flags & 512 /* TypeParameter */) ||
                (!callSignatures.length && !constructSignatures.length && !(funcType.flags & 16384 /* Union */) && isTypeAssignableTo(funcType, globalFunctionType))) {
                // 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);
                }
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray);
        }
        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'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);
            }
            // 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 && valueDecl.flags & 128 /* Abstract */) {
                error(node, ts.Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, ts.declarationNameToString(valueDecl.name));
                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);
                }
                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 (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 flags = declaration.flags;
            // Public constructor is accessible.
            if (!(flags & (8 /* Private */ | 16 /* Protected */))) {
                return true;
            }
            var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
            var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol);
            // A private or protected constructor can only be instantiated within it's own class
            if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                if (flags & 8 /* Private */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                if (flags & 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 */);
            if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & 16384 /* Union */) && isTypeAssignableTo(tagType, globalFunctionType))) {
                return resolveUntypedCall(node);
            }
            if (!callSignatures.length) {
                error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
                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 221 /* ClassDeclaration */:
                case 192 /* ClassExpression */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
                case 142 /* Parameter */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
                case 145 /* PropertyDeclaration */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
                case 147 /* MethodDeclaration */:
                case 149 /* GetAccessor */:
                case 150 /* 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 */);
            if (funcType === anyType || (!callSignatures.length && !(funcType.flags & 16384 /* Union */) && isTypeAssignableTo(funcType, globalFunctionType))) {
                return resolveUntypedCall(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);
                errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage);
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, errorInfo));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, headMessage);
        }
        function resolveSignature(node, candidatesOutArray) {
            switch (node.kind) {
                case 174 /* CallExpression */:
                    return resolveCallExpression(node, candidatesOutArray);
                case 175 /* NewExpression */:
                    return resolveNewExpression(node, candidatesOutArray);
                case 176 /* TaggedTemplateExpression */:
                    return resolveTaggedTemplateExpression(node, candidatesOutArray);
                case 143 /* Decorator */:
                    return resolveDecorator(node, candidatesOutArray);
            }
            ts.Debug.fail("Branch in 'resolveSignature' should be unreachable.");
        }
        // candidatesOutArray is passed by signature help in the language service, and collectCandidates
        // must fill it up with the appropriate candidate signatures
        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 !== anySignature && !candidatesOutArray) {
                return cached;
            }
            links.resolvedSignature = anySignature;
            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;
        }
        function getResolvedOrAnySignature(node) {
            // 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.
            return getNodeLinks(node).resolvedSignature === anySignature ? anySignature : getResolvedSignature(node);
        }
        function getInferredClassType(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.inferredClassType) {
                links.inferredClassType = createAnonymousType(undefined, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
            }
            return links.inferredClassType;
        }
        /**
         * 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, node.arguments);
            var signature = getResolvedSignature(node);
            if (node.expression.kind === 95 /* SuperKeyword */) {
                return voidType;
            }
            if (node.kind === 175 /* NewExpression */) {
                var declaration = signature.declaration;
                if (declaration &&
                    declaration.kind !== 148 /* Constructor */ &&
                    declaration.kind !== 152 /* ConstructSignature */ &&
                    declaration.kind !== 157 /* 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 = node.expression.kind === 69 /* Identifier */ ?
                        getResolvedSymbol(node.expression) :
                        checkExpression(node.expression).symbol;
                    if (funcSymbol && funcSymbol.members && (funcSymbol.flags & 16 /* Function */ || ts.isDeclarationOfFunctionExpression(funcSymbol))) {
                        return getInferredClassType(funcSymbol);
                    }
                    else if (compilerOptions.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) && ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
                return resolveExternalModuleTypeByLiteral(node.arguments[0]);
            }
            return getReturnTypeOfSignature(signature);
        }
        function checkTaggedTemplateExpression(node) {
            return getReturnTypeOfSignature(getResolvedSignature(node));
        }
        function checkAssertion(node) {
            var exprType = getRegularTypeOfObjectLiteral(checkExpression(node.expression));
            checkSourceElement(node.type);
            var targetType = getTypeFromTypeNode(node.type);
            if (produceDiagnostics && targetType !== unknownType) {
                var widenedType = getWidenedType(exprType);
                if (!isTypeComparableTo(targetType, widenedType)) {
                    checkTypeComparableTo(exprType, targetType, node, ts.Diagnostics.Type_0_cannot_be_converted_to_type_1);
                }
            }
            return targetType;
        }
        function checkNonNullAssertion(node) {
            return getNonNullableType(checkExpression(node.expression));
        }
        function getTypeOfParameter(symbol) {
            var type = getTypeOfSymbol(symbol);
            if (strictNullChecks) {
                var declaration = symbol.valueDeclaration;
                if (declaration && declaration.initializer) {
                    return addTypeKind(type, 32 /* 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 assignContextualParameterTypes(signature, context, mapper) {
            var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var parameter = signature.parameters[i];
                var contextualParameterType = getTypeAtPosition(context, i);
                assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
            }
            if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
                var parameter = ts.lastOrUndefined(signature.parameters);
                var contextualParameterType = getTypeOfSymbol(ts.lastOrUndefined(context.parameters));
                assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
            }
        }
        // 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(node) {
            if (ts.isBindingPattern(node.name)) {
                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (element.kind !== 193 /* OmittedExpression */) {
                        if (element.name.kind === 69 /* Identifier */) {
                            getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
                        }
                        assignBindingElementTypes(element);
                    }
                }
            }
        }
        function assignTypeToParameterAndFixTypeParameters(parameter, contextualType, mapper) {
            var links = getSymbolLinks(parameter);
            if (!links.type) {
                links.type = instantiateType(contextualType, mapper);
                // if inference didn't come up with anything but {}, fall back to the binding pattern if present.
                if (links.type === emptyObjectType &&
                    (parameter.valueDeclaration.name.kind === 167 /* ObjectBindingPattern */ ||
                        parameter.valueDeclaration.name.kind === 168 /* ArrayBindingPattern */)) {
                    links.type = getTypeFromBindingPattern(parameter.valueDeclaration.name);
                }
                assignBindingElementTypes(parameter.valueDeclaration);
            }
            else if (isInferentialContext(mapper)) {
                // Even if the parameter already has a type, it might be because it was given a type while
                // processing the function as an argument to a prior signature during overload resolution.
                // If this was the case, it may have caused some type parameters to be fixed. So here,
                // we need to ensure that type parameters at the same positions get fixed again. This is
                // done by calling instantiateType to attach the mapper to the contextualType, and then
                // calling inferTypes to force a walk of contextualType so that all the correct fixing
                // happens. The choice to pass in links.type may seem kind of arbitrary, but it serves
                // to make sure that all the correct positions in contextualType are reached by the walk.
                // Here is an example:
                //
                //      interface Base {
                //          baseProp;
                //      }
                //      interface Derived extends Base {
                //          toBase(): Base;
                //      }
                //
                //      var derived: Derived;
                //
                //      declare function foo<T>(x: T, func: (p: T) => T): T;
                //      declare function foo<T>(x: T, func: (p: T) => T): T;
                //
                //      var result = foo(derived, d => d.toBase());
                //
                // We are typing d while checking the second overload. But we've already given d
                // a type (Derived) from the first overload. However, we still want to fix the
                // T in the second overload so that we do not infer Base as a candidate for T
                // (inferring Base would make type argument inference inconsistent between the two
                // overloads).
                inferTypes(mapper.context, links.type, instantiateType(contextualType, mapper));
            }
        }
        function getReturnTypeFromJSDocComment(func) {
            var returnTag = ts.getJSDocReturnTag(func);
            if (returnTag && returnTag.typeExpression) {
                return getTypeFromTypeNode(returnTag.typeExpression.type);
            }
            return undefined;
        }
        function createPromiseType(promisedType) {
            // creates a `Promise<T>` type where `T` is the promisedType argument
            var globalPromiseType = getGlobalPromiseType();
            if (globalPromiseType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType);
                return createTypeReference(globalPromiseType, [promisedType]);
            }
            return emptyObjectType;
        }
        function createPromiseReturnType(func, promisedType) {
            var promiseType = createPromiseType(promisedType);
            if (promiseType === emptyObjectType) {
                error(func, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
                return unknownType;
            }
            return promiseType;
        }
        function getReturnTypeFromBody(func, contextualMapper) {
            var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
            if (!func.body) {
                return unknownType;
            }
            var isAsync = ts.isAsyncFunctionLike(func);
            var type;
            if (func.body.kind !== 199 /* Block */) {
                type = checkExpressionCached(func.body, contextualMapper);
                if (isAsync) {
                    // 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, func, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
                }
            }
            else {
                var types = void 0;
                var funcIsGenerator = !!func.asteriskToken;
                if (funcIsGenerator) {
                    types = checkAndAggregateYieldOperandTypes(func, contextualMapper);
                    if (types.length === 0) {
                        var iterableIteratorAny = createIterableIteratorType(anyType);
                        if (compilerOptions.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, contextualMapper);
                    if (!types) {
                        // For an async function, the return type will not be never, but rather a Promise for never.
                        return isAsync ? createPromiseReturnType(func, neverType) : neverType;
                    }
                    if (types.length === 0) {
                        // For an async function, the return type will not be void, but rather a Promise for void.
                        return isAsync ? createPromiseReturnType(func, voidType) : voidType;
                    }
                }
                // When yield/return statements are contextually typed we allow the return type to be a union type.
                // Otherwise we require the yield/return expressions to have a best common supertype.
                type = contextualSignature ? getUnionType(types) : getCommonSupertype(types);
                if (!type) {
                    if (funcIsGenerator) {
                        error(func, ts.Diagnostics.No_best_common_type_exists_among_yield_expressions);
                        return createIterableIteratorType(unknownType);
                    }
                    else {
                        error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions);
                        // Defer to unioning the return types so we get a) downstream errors earlier and b) better Salsa experience
                        return isAsync ? createPromiseReturnType(func, getUnionType(types)) : getUnionType(types);
                    }
                }
                if (funcIsGenerator) {
                    type = createIterableIteratorType(type);
                }
            }
            if (!contextualSignature) {
                reportErrorsFromWidening(func, 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 isAsync ? createPromiseReturnType(func, widenedType) : widenedType;
        }
        function checkAndAggregateYieldOperandTypes(func, contextualMapper) {
            var aggregatedTypes = [];
            ts.forEachYieldExpression(func.body, function (yieldExpression) {
                var expr = yieldExpression.expression;
                if (expr) {
                    var type = checkExpressionCached(expr, contextualMapper);
                    if (yieldExpression.asteriskToken) {
                        // A yield* expression effectively yields everything that its operand yields
                        type = checkElementTypeOfIterable(type, yieldExpression.expression);
                    }
                    if (!ts.contains(aggregatedTypes, type)) {
                        aggregatedTypes.push(type);
                    }
                }
            });
            return aggregatedTypes;
        }
        function isExhaustiveSwitchStatement(node) {
            var expr = node.expression;
            if (!node.possiblyExhaustive || expr.kind !== 172 /* PropertyAccessExpression */) {
                return false;
            }
            var type = checkExpression(expr.expression);
            if (!(type.flags & 16384 /* Union */)) {
                return false;
            }
            var propName = expr.name.text;
            var propType = getTypeOfPropertyOfType(type, propName);
            if (!propType || !isStringLiteralUnionType(propType)) {
                return false;
            }
            var switchTypes = getSwitchClauseTypes(node);
            if (!switchTypes.length) {
                return false;
            }
            return eachTypeContainedIn(propType, switchTypes);
        }
        function functionHasImplicitReturn(func) {
            if (!(func.flags & 32768 /* HasImplicitReturn */)) {
                return false;
            }
            var lastStatement = ts.lastOrUndefined(func.body.statements);
            if (lastStatement && lastStatement.kind === 213 /* SwitchStatement */ && isExhaustiveSwitchStatement(lastStatement)) {
                return false;
            }
            return true;
        }
        function checkAndAggregateReturnExpressionTypes(func, contextualMapper) {
            var isAsync = ts.isAsyncFunctionLike(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, contextualMapper);
                    if (isAsync) {
                        // 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.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
                    }
                    if (type === neverType) {
                        hasReturnOfTypeNever = true;
                    }
                    else if (!ts.contains(aggregatedTypes, type)) {
                        aggregatedTypes.push(type);
                    }
                }
                else {
                    hasReturnWithNoExpression = true;
                }
            });
            if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever ||
                func.kind === 179 /* FunctionExpression */ || func.kind === 180 /* ArrowFunction */)) {
                return undefined;
            }
            if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) {
                if (!ts.contains(aggregatedTypes, undefinedType)) {
                    aggregatedTypes.push(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 */ | 16 /* 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 !== 199 /* Block */ || !functionHasImplicitReturn(func)) {
                return;
            }
            var hasExplicitReturn = func.flags & 65536 /* HasExplicitReturn */;
            if (returnType === neverType) {
                error(func.type, 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(func.type, ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
            }
            else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) {
                error(func.type, 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(func.type || func, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper) {
            ts.Debug.assert(node.kind !== 147 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            // Grammar checking
            var hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
            if (!hasGrammarError && node.kind === 179 /* FunctionExpression */) {
                checkGrammarForGenerator(node);
            }
            // The identityMapper object is used to indicate that function expressions are wildcards
            if (contextualMapper === identityMapper && isContextSensitive(node)) {
                checkNodeDeferred(node);
                return anyFunctionType;
            }
            var links = getNodeLinks(node);
            var type = getTypeOfSymbol(node.symbol);
            var contextSensitive = isContextSensitive(node);
            var mightFixTypeParameters = contextSensitive && isInferentialContext(contextualMapper);
            // Check if function expression is contextually typed and assign parameter types if so.
            // See the comment in assignTypeToParameterAndFixTypeParameters to understand why we need to
            // check mightFixTypeParameters.
            if (mightFixTypeParameters || !(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.
                var contextChecked = !!(links.flags & 1024 /* ContextChecked */);
                if (mightFixTypeParameters || !contextChecked) {
                    links.flags |= 1024 /* ContextChecked */;
                    if (contextualSignature) {
                        var signature = getSignaturesOfType(type, 0 /* Call */)[0];
                        if (contextSensitive) {
                            assignContextualParameterTypes(signature, contextualSignature, contextualMapper || identityMapper);
                        }
                        if (mightFixTypeParameters || !node.type && !signature.resolvedReturnType) {
                            var returnType = getReturnTypeFromBody(node, contextualMapper);
                            if (!signature.resolvedReturnType) {
                                signature.resolvedReturnType = returnType;
                            }
                        }
                    }
                    if (!contextChecked) {
                        checkSignatureDeclaration(node);
                        checkNodeDeferred(node);
                    }
                }
            }
            if (produceDiagnostics && node.kind !== 147 /* MethodDeclaration */ && node.kind !== 146 /* MethodSignature */) {
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
            }
            return type;
        }
        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) {
            ts.Debug.assert(node.kind !== 147 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var isAsync = ts.isAsyncFunctionLike(node);
            var returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
            if (!node.asteriskToken) {
                // return is not necessary in the body of generators
                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
            }
            if (node.body) {
                if (!node.type) {
                    // 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 === 199 /* 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 (isAsync) {
                            var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member);
                            checkTypeAssignableTo(awaitedType, returnOrPromisedType, node.body);
                        }
                        else {
                            checkTypeAssignableTo(exprType, returnOrPromisedType, node.body);
                        }
                    }
                }
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkArithmeticOperandType(operand, type, diagnostic) {
            if (!isTypeAnyOrAllConstituentTypesHaveKind(type, 132 /* 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 symbol.isReadonly ||
                symbol.flags & 4 /* Property */ && (getDeclarationFlagsFromSymbol(symbol) & 64 /* Readonly */) !== 0 ||
                symbol.flags & 3 /* Variable */ && (getDeclarationFlagsFromSymbol(symbol) & 2048 /* Const */) !== 0 ||
                symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) ||
                (symbol.flags & 8 /* EnumMember */) !== 0;
        }
        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 === 172 /* PropertyAccessExpression */ || expr.kind === 173 /* ElementAccessExpression */) &&
                    expr.expression.kind === 97 /* 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 === 148 /* 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 === 172 /* PropertyAccessExpression */ || expr.kind === 173 /* ElementAccessExpression */) {
                var node = skipParenthesizedNodes(expr.expression);
                if (node.kind === 69 /* Identifier */) {
                    var symbol = getNodeLinks(node).resolvedSymbol;
                    if (symbol.flags & 8388608 /* Alias */) {
                        var declaration = getDeclarationOfAliasSymbol(symbol);
                        return declaration && declaration.kind === 232 /* NamespaceImport */;
                    }
                }
            }
            return false;
        }
        function checkReferenceExpression(expr, invalidReferenceMessage, constantVariableMessage) {
            // References are combinations of identifiers, parentheses, and property accesses.
            var node = skipParenthesizedNodes(expr);
            if (node.kind !== 69 /* Identifier */ && node.kind !== 172 /* PropertyAccessExpression */ && node.kind !== 173 /* ElementAccessExpression */) {
                error(expr, invalidReferenceMessage);
                return false;
            }
            // Because we get the symbol from the resolvedSymbol property, it might be of kind
            // SymbolFlags.ExportValue. In this case it is necessary to get the actual export
            // symbol, which will have the correct flags set on it.
            var links = getNodeLinks(node);
            var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol);
            if (symbol) {
                if (symbol !== unknownSymbol && symbol !== argumentsSymbol) {
                    // Only variables (and not functions, classes, namespaces, enum objects, or enum members)
                    // are considered references when referenced using a simple identifier.
                    if (node.kind === 69 /* Identifier */ && !(symbol.flags & 3 /* Variable */)) {
                        error(expr, invalidReferenceMessage);
                        return false;
                    }
                    if (isReferenceToReadonlyEntity(node, symbol) || isReferenceThroughNamespaceImport(node)) {
                        error(expr, constantVariableMessage);
                        return false;
                    }
                }
            }
            else if (node.kind === 173 /* ElementAccessExpression */) {
                if (links.resolvedIndexInfo && links.resolvedIndexInfo.isReadonly) {
                    error(expr, constantVariableMessage);
                    return false;
                }
            }
            return true;
        }
        function checkDeleteExpression(node) {
            checkExpression(node.expression);
            return booleanType;
        }
        function checkTypeOfExpression(node) {
            checkExpression(node.expression);
            return stringType;
        }
        function checkVoidExpression(node) {
            checkExpression(node.expression);
            return undefinedWideningType;
        }
        function checkAwaitExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 33554432 /* 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);
        }
        function checkPrefixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            switch (node.operator) {
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                case 50 /* TildeToken */:
                    if (maybeTypeOfKind(operandType, 16777216 /* ESSymbol */)) {
                        error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator));
                    }
                    return numberType;
                case 49 /* ExclamationToken */:
                    return booleanType;
                case 41 /* PlusPlusToken */:
                case 42 /* MinusMinusToken */:
                    var ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType), 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_property_or_indexer, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant_or_a_read_only_property);
                    }
                    return numberType;
            }
            return unknownType;
        }
        function checkPostfixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            var ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType), 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_property_or_indexer, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant_or_a_read_only_property);
            }
            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 & 49152 /* UnionOrIntersection */) {
                var types = type.types;
                for (var _i = 0, types_10 = types; _i < types_10.length; _i++) {
                    var t = types_10[_i];
                    if (maybeTypeOfKind(t, kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Return true if type is of the given kind. A union type is of a given kind if all constituent types
        // are of the given kind. An intersection type is of a given kind if at least one constituent type is
        // of the given kind.
        function isTypeOfKind(type, kind) {
            if (type.flags & kind) {
                return true;
            }
            if (type.flags & 16384 /* Union */) {
                var types = type.types;
                for (var _i = 0, types_11 = types; _i < types_11.length; _i++) {
                    var t = types_11[_i];
                    if (!isTypeOfKind(t, kind)) {
                        return false;
                    }
                }
                return true;
            }
            if (type.flags & 32768 /* Intersection */) {
                var types = type.types;
                for (var _a = 0, types_12 = types; _a < types_12.length; _a++) {
                    var t = types_12[_a];
                    if (isTypeOfKind(t, kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isConstEnumObjectType(type) {
            return type.flags & (80896 /* ObjectType */ | 65536 /* Anonymous */) && type.symbol && isConstEnumSymbol(type.symbol);
        }
        function isConstEnumSymbol(symbol) {
            return (symbol.flags & 128 /* ConstEnum */) !== 0;
        }
        function checkInstanceOfExpression(left, right, leftType, rightType) {
            // 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 or a subtype of the 'Function' interface type.
            // 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 (isTypeOfKind(leftType, 16777726 /* 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) || 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) {
            // 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 (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, 258 /* StringLike */ | 132 /* NumberLike */ | 16777216 /* ESSymbol */)) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
            }
            if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 80896 /* ObjectType */ | 512 /* TypeParameter */)) {
                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, contextualMapper) {
            var properties = node.properties;
            for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
                var p = properties_3[_i];
                checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, contextualMapper);
            }
            return sourceType;
        }
        function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType, property, contextualMapper) {
            if (property.kind === 253 /* PropertyAssignment */ || property.kind === 254 /* ShorthandPropertyAssignment */) {
                var name_14 = property.name;
                if (name_14.kind === 140 /* ComputedPropertyName */) {
                    checkComputedPropertyName(name_14);
                }
                if (isComputedNonLiteralName(name_14)) {
                    return undefined;
                }
                var text = getTextOfPropertyName(name_14);
                var type = isTypeAny(objectLiteralType)
                    ? objectLiteralType
                    : getTypeOfPropertyOfType(objectLiteralType, text) ||
                        isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, 1 /* Number */) ||
                        getIndexTypeOfType(objectLiteralType, 0 /* String */);
                if (type) {
                    if (property.kind === 254 /* ShorthandPropertyAssignment */) {
                        return checkDestructuringAssignment(property, type);
                    }
                    else {
                        // non-shorthand property assignments should always have initializers
                        return checkDestructuringAssignment(property.initializer, type);
                    }
                }
                else {
                    error(name_14, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), ts.declarationNameToString(name_14));
                }
            }
            else {
                error(property, ts.Diagnostics.Property_assignment_expected);
            }
        }
        function checkArrayLiteralAssignment(node, sourceType, contextualMapper) {
            // 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) || unknownType;
            var elements = node.elements;
            for (var i = 0; i < elements.length; i++) {
                checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, contextualMapper);
            }
            return sourceType;
        }
        function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, contextualMapper) {
            var elements = node.elements;
            var element = elements[elementIndex];
            if (element.kind !== 193 /* OmittedExpression */) {
                if (element.kind !== 191 /* SpreadElementExpression */) {
                    var propName = "" + elementIndex;
                    var type = isTypeAny(sourceType)
                        ? sourceType
                        : isTupleLikeType(sourceType)
                            ? getTypeOfPropertyOfType(sourceType, propName)
                            : elementType;
                    if (type) {
                        return checkDestructuringAssignment(element, type, contextualMapper);
                    }
                    else {
                        if (isTupleType(sourceType)) {
                            error(element, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), sourceType.elementTypes.length, 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_an_array_destructuring_pattern);
                    }
                    else {
                        var restExpression = element.expression;
                        if (restExpression.kind === 187 /* BinaryExpression */ && restExpression.operatorToken.kind === 56 /* EqualsToken */) {
                            error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                        }
                        else {
                            return checkDestructuringAssignment(restExpression, createArrayType(elementType), contextualMapper);
                        }
                    }
                }
            }
            return undefined;
        }
        function checkDestructuringAssignment(exprOrAssignment, sourceType, contextualMapper) {
            var target;
            if (exprOrAssignment.kind === 254 /* 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 &&
                        !(getCombinedTypeFlags(checkExpression(prop.objectAssignmentInitializer)) & 32 /* Undefined */)) {
                        sourceType = getTypeWithFacts(sourceType, 131072 /* NEUndefined */);
                    }
                    checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, contextualMapper);
                }
                target = exprOrAssignment.name;
            }
            else {
                target = exprOrAssignment;
            }
            if (target.kind === 187 /* BinaryExpression */ && target.operatorToken.kind === 56 /* EqualsToken */) {
                checkBinaryExpression(target, contextualMapper);
                target = target.left;
            }
            if (target.kind === 171 /* ObjectLiteralExpression */) {
                return checkObjectLiteralAssignment(target, sourceType, contextualMapper);
            }
            if (target.kind === 170 /* ArrayLiteralExpression */) {
                return checkArrayLiteralAssignment(target, sourceType, contextualMapper);
            }
            return checkReferenceAssignment(target, sourceType, contextualMapper);
        }
        function checkReferenceAssignment(target, sourceType, contextualMapper) {
            var targetType = checkExpression(target, contextualMapper);
            if (checkReferenceExpression(target, ts.Diagnostics.Invalid_left_hand_side_of_assignment_expression, ts.Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant_or_a_read_only_property)) {
                checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined);
            }
            return sourceType;
        }
        function isTypeEqualityComparableTo(source, target) {
            return (target.flags & 96 /* Nullable */) !== 0 || isTypeComparableTo(source, target);
        }
        function checkBinaryExpression(node, contextualMapper) {
            return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
        }
        function checkBinaryLikeExpression(left, operatorToken, right, contextualMapper, errorNode) {
            var operator = operatorToken.kind;
            if (operator === 56 /* EqualsToken */ && (left.kind === 171 /* ObjectLiteralExpression */ || left.kind === 170 /* ArrayLiteralExpression */)) {
                return checkDestructuringAssignment(left, checkExpression(right, contextualMapper), contextualMapper);
            }
            var leftType = checkExpression(left, contextualMapper);
            var rightType = checkExpression(right, contextualMapper);
            switch (operator) {
                case 37 /* AsteriskToken */:
                case 38 /* AsteriskAsteriskToken */:
                case 59 /* AsteriskEqualsToken */:
                case 60 /* AsteriskAsteriskEqualsToken */:
                case 39 /* SlashToken */:
                case 61 /* SlashEqualsToken */:
                case 40 /* PercentToken */:
                case 62 /* PercentEqualsToken */:
                case 36 /* MinusToken */:
                case 58 /* MinusEqualsToken */:
                case 43 /* LessThanLessThanToken */:
                case 63 /* LessThanLessThanEqualsToken */:
                case 44 /* GreaterThanGreaterThanToken */:
                case 64 /* GreaterThanGreaterThanEqualsToken */:
                case 45 /* GreaterThanGreaterThanGreaterThanToken */:
                case 65 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 47 /* BarToken */:
                case 67 /* BarEqualsToken */:
                case 48 /* CaretToken */:
                case 68 /* CaretEqualsToken */:
                case 46 /* AmpersandToken */:
                case 66 /* AmpersandEqualsToken */:
                    // TypeScript 1.0 spec (April 2014): 4.19.1
                    // These operators require their operands to be of type Any, the Number primitive type,
                    // or an enum type. Operands of an enum type are treated
                    // as having the primitive type Number. If one operand is the null or undefined value,
                    // it is treated as having the type of the other operand.
                    // The result is always of the Number primitive type.
                    if (leftType.flags & 96 /* Nullable */)
                        leftType = rightType;
                    if (rightType.flags & 96 /* Nullable */)
                        rightType = leftType;
                    leftType = getNonNullableType(leftType);
                    rightType = getNonNullableType(rightType);
                    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 & 8 /* Boolean */) &&
                        (rightType.flags & 8 /* Boolean */) &&
                        (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 35 /* PlusToken */:
                case 57 /* PlusEqualsToken */:
                    // TypeScript 1.0 spec (April 2014): 4.19.2
                    // The binary + operator requires both operands to be of the Number primitive type or an enum type,
                    // or at least one of the operands to be of type Any or the String primitive type.
                    // If one operand is the null or undefined value, it is treated as having the type of the other operand.
                    if (leftType.flags & 96 /* Nullable */)
                        leftType = rightType;
                    if (rightType.flags & 96 /* Nullable */)
                        rightType = leftType;
                    leftType = getNonNullableType(leftType);
                    rightType = getNonNullableType(rightType);
                    var resultType = void 0;
                    if (isTypeOfKind(leftType, 132 /* NumberLike */) && isTypeOfKind(rightType, 132 /* NumberLike */)) {
                        // 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 (isTypeOfKind(leftType, 258 /* StringLike */) || isTypeOfKind(rightType, 258 /* StringLike */)) {
                            // 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 === 57 /* PlusEqualsToken */) {
                        checkAssignmentOperator(resultType);
                    }
                    return resultType;
                case 25 /* LessThanToken */:
                case 27 /* GreaterThanToken */:
                case 28 /* LessThanEqualsToken */:
                case 29 /* GreaterThanEqualsToken */:
                    if (checkForDisallowedESSymbolOperand(operator)) {
                        if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
                            reportOperatorError();
                        }
                    }
                    return booleanType;
                case 30 /* EqualsEqualsToken */:
                case 31 /* ExclamationEqualsToken */:
                case 32 /* EqualsEqualsEqualsToken */:
                case 33 /* ExclamationEqualsEqualsToken */:
                    if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
                        reportOperatorError();
                    }
                    return booleanType;
                case 91 /* InstanceOfKeyword */:
                    return checkInstanceOfExpression(left, right, leftType, rightType);
                case 90 /* InKeyword */:
                    return checkInExpression(left, right, leftType, rightType);
                case 51 /* AmpersandAmpersandToken */:
                    return strictNullChecks ? addTypeKind(rightType, getCombinedTypeFlags(leftType) & 112 /* Falsy */) : rightType;
                case 52 /* BarBarToken */:
                    return getUnionType([getNonNullableType(leftType), rightType]);
                case 56 /* EqualsToken */:
                    checkAssignmentOperator(rightType);
                    return getRegularTypeOfObjectLiteral(rightType);
                case 24 /* CommaToken */:
                    return rightType;
            }
            // Return true if there was no error, false if there was an error.
            function checkForDisallowedESSymbolOperand(operator) {
                var offendingSymbolOperand = maybeTypeOfKind(leftType, 16777216 /* ESSymbol */) ? left :
                    maybeTypeOfKind(rightType, 16777216 /* 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 47 /* BarToken */:
                    case 67 /* BarEqualsToken */:
                        return 52 /* BarBarToken */;
                    case 48 /* CaretToken */:
                    case 68 /* CaretEqualsToken */:
                        return 33 /* ExclamationEqualsEqualsToken */;
                    case 46 /* AmpersandToken */:
                    case 66 /* AmpersandEqualsToken */:
                        return 51 /* AmpersandAmpersandToken */;
                    default:
                        return undefined;
                }
            }
            function checkAssignmentOperator(valueType) {
                if (produceDiagnostics && operator >= 56 /* FirstAssignment */ && operator <= 68 /* LastAssignment */) {
                    // 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.
                    var ok = checkReferenceExpression(left, ts.Diagnostics.Invalid_left_hand_side_of_assignment_expression, ts.Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant_or_a_read_only_property);
                    // Use default messages
                    if (ok) {
                        // 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 & 8388608 /* 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.
                if (func && func.asteriskToken) {
                    var expressionType = checkExpressionCached(node.expression, /*contextualMapper*/ undefined);
                    var expressionElementType = void 0;
                    var nodeIsYieldStar = !!node.asteriskToken;
                    if (nodeIsYieldStar) {
                        expressionElementType = checkElementTypeOfIterable(expressionType, node.expression);
                    }
                    // 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.
                    if (func.type) {
                        var signatureElementType = getElementTypeOfIterableIterator(getTypeFromTypeNode(func.type)) || anyType;
                        if (nodeIsYieldStar) {
                            checkTypeAssignableTo(expressionElementType, signatureElementType, node.expression, /*headMessage*/ undefined);
                        }
                        else {
                            checkTypeAssignableTo(expressionType, signatureElementType, node.expression, /*headMessage*/ undefined);
                        }
                    }
                }
            }
            // Both yield and yield* expressions have type 'any'
            return anyType;
        }
        function checkConditionalExpression(node, contextualMapper) {
            checkExpression(node.condition);
            var type1 = checkExpression(node.whenTrue, contextualMapper);
            var type2 = checkExpression(node.whenFalse, contextualMapper);
            return getUnionType([type1, type2]);
        }
        function checkStringLiteralExpression(node) {
            var contextualType = getContextualType(node);
            if (contextualType && isStringLiteralUnionType(contextualType)) {
                return getStringLiteralTypeForText(node.text);
            }
            return stringType;
        }
        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;
            node.contextualType = contextualType;
            var result = checkExpression(node, contextualMapper);
            node.contextualType = saveContextualType;
            return result;
        }
        function checkExpressionCached(node, contextualMapper) {
            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, contextualMapper);
                flowLoopStart = saveFlowLoopStart;
            }
            return links.resolvedType;
        }
        function checkPropertyAssignment(node, contextualMapper) {
            // 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 === 140 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            return checkExpression(node.initializer, contextualMapper);
        }
        function checkObjectLiteralMethod(node, contextualMapper) {
            // 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 === 140 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper);
            return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, contextualMapper);
        }
        function instantiateTypeWithSingleGenericCallSignature(node, type, contextualMapper) {
            if (isInferentialContext(contextualMapper)) {
                var signature = getSingleCallSignature(type);
                if (signature && signature.typeParameters) {
                    var contextualType = getApparentTypeOfContextualType(node);
                    if (contextualType) {
                        var contextualSignature = getSingleCallSignature(contextualType);
                        if (contextualSignature && !contextualSignature.typeParameters) {
                            return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper));
                        }
                    }
                }
            }
            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, contextualMapper) {
            var type;
            if (node.kind === 139 /* QualifiedName */) {
                type = checkQualifiedName(node);
            }
            else {
                var uninstantiatedType = checkExpressionWorker(node, contextualMapper);
                type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, contextualMapper);
            }
            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 === 172 /* PropertyAccessExpression */ && node.parent.expression === node) ||
                    (node.parent.kind === 173 /* ElementAccessExpression */ && node.parent.expression === node) ||
                    ((node.kind === 69 /* Identifier */ || node.kind === 139 /* 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 checkNumericLiteral(node) {
            // Grammar checking
            checkGrammarNumericLiteral(node);
            return numberType;
        }
        function checkExpressionWorker(node, contextualMapper) {
            switch (node.kind) {
                case 69 /* Identifier */:
                    return checkIdentifier(node);
                case 97 /* ThisKeyword */:
                    return checkThisExpression(node);
                case 95 /* SuperKeyword */:
                    return checkSuperExpression(node);
                case 93 /* NullKeyword */:
                    return nullWideningType;
                case 99 /* TrueKeyword */:
                case 84 /* FalseKeyword */:
                    return booleanType;
                case 8 /* NumericLiteral */:
                    return checkNumericLiteral(node);
                case 189 /* TemplateExpression */:
                    return checkTemplateExpression(node);
                case 9 /* StringLiteral */:
                    return checkStringLiteralExpression(node);
                case 11 /* NoSubstitutionTemplateLiteral */:
                    return stringType;
                case 10 /* RegularExpressionLiteral */:
                    return globalRegExpType;
                case 170 /* ArrayLiteralExpression */:
                    return checkArrayLiteral(node, contextualMapper);
                case 171 /* ObjectLiteralExpression */:
                    return checkObjectLiteral(node, contextualMapper);
                case 172 /* PropertyAccessExpression */:
                    return checkPropertyAccessExpression(node);
                case 173 /* ElementAccessExpression */:
                    return checkIndexedAccess(node);
                case 174 /* CallExpression */:
                case 175 /* NewExpression */:
                    return checkCallExpression(node);
                case 176 /* TaggedTemplateExpression */:
                    return checkTaggedTemplateExpression(node);
                case 178 /* ParenthesizedExpression */:
                    return checkExpression(node.expression, contextualMapper);
                case 192 /* ClassExpression */:
                    return checkClassExpression(node);
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    return checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper);
                case 182 /* TypeOfExpression */:
                    return checkTypeOfExpression(node);
                case 177 /* TypeAssertionExpression */:
                case 195 /* AsExpression */:
                    return checkAssertion(node);
                case 196 /* NonNullExpression */:
                    return checkNonNullAssertion(node);
                case 181 /* DeleteExpression */:
                    return checkDeleteExpression(node);
                case 183 /* VoidExpression */:
                    return checkVoidExpression(node);
                case 184 /* AwaitExpression */:
                    return checkAwaitExpression(node);
                case 185 /* PrefixUnaryExpression */:
                    return checkPrefixUnaryExpression(node);
                case 186 /* PostfixUnaryExpression */:
                    return checkPostfixUnaryExpression(node);
                case 187 /* BinaryExpression */:
                    return checkBinaryExpression(node, contextualMapper);
                case 188 /* ConditionalExpression */:
                    return checkConditionalExpression(node, contextualMapper);
                case 191 /* SpreadElementExpression */:
                    return checkSpreadElementExpression(node, contextualMapper);
                case 193 /* OmittedExpression */:
                    return undefinedWideningType;
                case 190 /* YieldExpression */:
                    return checkYieldExpression(node);
                case 248 /* JsxExpression */:
                    return checkJsxExpression(node);
                case 241 /* JsxElement */:
                    return checkJsxElement(node);
                case 242 /* JsxSelfClosingElement */:
                    return checkJsxSelfClosingElement(node);
                case 243 /* 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);
            getConstraintOfTypeParameter(getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)));
            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 (node.flags & 92 /* ParameterPropertyModifier */) {
                func = ts.getContainingFunction(node);
                if (!(func.kind === 148 /* 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.text === "this") {
                if (ts.indexOf(func.parameters, node) !== 0) {
                    error(node, ts.Diagnostics.A_this_parameter_must_be_the_first_parameter);
                }
                if (func.kind === 148 /* Constructor */ || func.kind === 152 /* ConstructSignature */ || func.kind === 157 /* 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 isSyntacticallyValidGenerator(node) {
            if (!node.asteriskToken || !node.body) {
                return false;
            }
            return node.kind === 147 /* MethodDeclaration */ ||
                node.kind === 220 /* FunctionDeclaration */ ||
                node.kind === 179 /* FunctionExpression */;
        }
        function getTypePredicateParameterIndex(parameterList, parameter) {
            if (parameterList) {
                for (var i = 0; i < parameterList.length; i++) {
                    var param = parameterList[i];
                    if (param.name.kind === 69 /* Identifier */ &&
                        param.name.text === parameter.text) {
                        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;
            }
            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(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_15 = _a[_i].name;
                        if (ts.isBindingPattern(name_15) &&
                            checkIfTypePredicateVariableIsDeclaredInBindingPattern(name_15, 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 180 /* ArrowFunction */:
                case 151 /* CallSignature */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 156 /* FunctionType */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                    var parent_10 = node.parent;
                    if (node === parent_10.type) {
                        return parent_10;
                    }
            }
        }
        function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var name_16 = _a[_i].name;
                if (name_16.kind === 69 /* Identifier */ &&
                    name_16.text === predicateVariableName) {
                    error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName);
                    return true;
                }
                else if (name_16.kind === 168 /* ArrayBindingPattern */ ||
                    name_16.kind === 167 /* ObjectBindingPattern */) {
                    if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name_16, predicateVariableNode, predicateVariableName)) {
                        return true;
                    }
                }
            }
        }
        function checkSignatureDeclaration(node) {
            // Grammar checking
            if (node.kind === 153 /* IndexSignature */) {
                checkGrammarIndexSignature(node);
            }
            else if (node.kind === 156 /* FunctionType */ || node.kind === 220 /* FunctionDeclaration */ || node.kind === 157 /* ConstructorType */ ||
                node.kind === 151 /* CallSignature */ || node.kind === 148 /* Constructor */ ||
                node.kind === 152 /* ConstructSignature */) {
                checkGrammarFunctionLikeDeclaration(node);
            }
            checkTypeParameters(node.typeParameters);
            ts.forEach(node.parameters, checkParameter);
            if (node.type) {
                checkSourceElement(node.type);
            }
            if (produceDiagnostics) {
                checkCollisionWithArgumentsInGeneratedCode(node);
                if (compilerOptions.noImplicitAny && !node.type) {
                    switch (node.kind) {
                        case 152 /* ConstructSignature */:
                            error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                        case 151 /* CallSignature */:
                            error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                    }
                }
                if (node.type) {
                    if (languageVersion >= 2 /* ES6 */ && isSyntacticallyValidGenerator(node)) {
                        var returnType = getTypeFromTypeNode(node.type);
                        if (returnType === voidType) {
                            error(node.type, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation);
                        }
                        else {
                            var generatorElementType = getElementTypeOfIterableIterator(returnType) || anyType;
                            var iterableIteratorInstantiation = createIterableIteratorType(generatorElementType);
                            // 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, node.type);
                        }
                    }
                    else if (ts.isAsyncFunctionLike(node)) {
                        checkAsyncFunctionReturnType(node);
                    }
                }
                if (!node.body) {
                    checkUnusedTypeParameters(node);
                }
            }
        }
        function checkClassForDuplicateDeclarations(node) {
            var getter = 1, setter = 2, property = getter | setter;
            var instanceNames = {};
            var staticNames = {};
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 148 /* Constructor */) {
                    for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                        var param = _c[_b];
                        if (ts.isParameterPropertyDeclaration(param)) {
                            addName(instanceNames, param.name, param.name.text, property);
                        }
                    }
                }
                else {
                    var isStatic = ts.forEach(member.modifiers, function (m) { return m.kind === 113 /* StaticKeyword */; });
                    var names = isStatic ? staticNames : instanceNames;
                    var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name);
                    if (memberName) {
                        switch (member.kind) {
                            case 149 /* GetAccessor */:
                                addName(names, member.name, memberName, getter);
                                break;
                            case 150 /* SetAccessor */:
                                addName(names, member.name, memberName, setter);
                                break;
                            case 145 /* PropertyDeclaration */:
                                addName(names, member.name, memberName, property);
                                break;
                        }
                    }
                }
            }
            function addName(names, location, name, meaning) {
                if (ts.hasProperty(names, name)) {
                    var prev = names[name];
                    if (prev & meaning) {
                        error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                    }
                    else {
                        names[name] = prev | meaning;
                    }
                }
                else {
                    names[name] = meaning;
                }
            }
        }
        function checkObjectTypeForDuplicateDeclarations(node) {
            var names = {};
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind == 144 /* PropertySignature */) {
                    var memberName = void 0;
                    switch (member.name.kind) {
                        case 9 /* StringLiteral */:
                        case 8 /* NumericLiteral */:
                        case 69 /* Identifier */:
                            memberName = member.name.text;
                            break;
                        default:
                            continue;
                    }
                    if (ts.hasProperty(names, memberName)) {
                        error(member.symbol.valueDeclaration.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
                        error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
                    }
                    else {
                        names[memberName] = true;
                    }
                }
            }
        }
        function checkTypeForDuplicateIndexSignatures(node) {
            if (node.kind === 222 /* 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 132 /* StringKeyword */:
                                if (!seenStringIndexer) {
                                    seenStringIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
                                }
                                break;
                            case 130 /* 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 (node.flags & 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) {
                return n.name && containsSuperCall(n.name);
            }
            function containsSuperCall(n) {
                if (ts.isSuperCallExpression(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 markThisReferencesAsErrors(n) {
                if (n.kind === 97 /* ThisKeyword */) {
                    error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                }
                else if (n.kind !== 179 /* FunctionExpression */ && n.kind !== 220 /* FunctionDeclaration */) {
                    ts.forEachChild(n, markThisReferencesAsErrors);
                }
            }
            function isInstancePropertyWithInitializer(n) {
                return n.kind === 145 /* PropertyDeclaration */ &&
                    !(n.flags & 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)) {
                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.forEach(node.parent.members, isInstancePropertyWithInitializer) ||
                        ts.forEach(node.parameters, function (p) { return p.flags & 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 === 202 /* ExpressionStatement */ && ts.isSuperCallExpression(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 === 149 /* GetAccessor */) {
                    if (!ts.isInAmbientContext(node) && ts.nodeIsPresent(node.body) && (node.flags & 32768 /* HasImplicitReturn */)) {
                        if (node.flags & 65536 /* HasExplicitReturn */) {
                            if (compilerOptions.noImplicitReturns) {
                                error(node.name, ts.Diagnostics.Not_all_code_paths_return_a_value);
                            }
                        }
                        else {
                            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 === 140 /* 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 === 149 /* GetAccessor */ ? 150 /* SetAccessor */ : 149 /* GetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(node.symbol, otherKind);
                    if (otherAccessor) {
                        if (((node.flags & 28 /* AccessibilityModifier */) !== (otherAccessor.flags & 28 /* AccessibilityModifier */))) {
                            error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
                        }
                        if (((node.flags & 128 /* Abstract */) !== (otherAccessor.flags & 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);
                    }
                }
                getTypeOfAccessors(getSymbolOfNode(node));
            }
            if (node.parent.kind !== 171 /* ObjectLiteralExpression */) {
                checkSourceElement(node.body);
                registerForUnusedIdentifiersCheck(node);
            }
            else {
                checkNodeDeferred(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 checkAccessorDeferred(node) {
            checkSourceElement(node.body);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkMissingDeclaration(node) {
            checkDecorators(node);
        }
        function checkTypeArgumentConstraints(typeParameters, typeArgumentNodes) {
            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 = ts.map(typeArgumentNodes, getTypeFromTypeNode);
                        mapper = createTypeMapper(typeParameters, typeArguments);
                    }
                    var typeArgument = typeArguments[i];
                    result = result && checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), typeArgumentNodes[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                }
            }
            return result;
        }
        function checkTypeReferenceNode(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            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;
                        var typeParameters = symbol.flags & 524288 /* TypeAlias */ ? getSymbolLinks(symbol).typeParameters : type.target.localTypeParameters;
                        checkTypeArgumentConstraints(typeParameters, node.typeArguments);
                    }
                }
            }
        }
        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 isPrivateWithinAmbient(node) {
            return (node.flags & 8 /* Private */) && ts.isInAmbientContext(node);
        }
        function getEffectiveDeclarationFlags(n, flagsToCheck) {
            var flags = ts.getCombinedNodeFlags(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 !== 222 /* InterfaceDeclaration */ &&
                n.parent.kind !== 221 /* ClassDeclaration */ &&
                n.parent.kind !== 192 /* 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(o.name, ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
                        }
                        else if (deviation & 2 /* Ambient */) {
                            error(o.name, ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
                        }
                        else if (deviation & (8 /* Private */ | 16 /* Protected */)) {
                            error(o.name || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
                        }
                        else if (deviation & 128 /* Abstract */) {
                            error(o.name, 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(o.name, 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;
            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(jfreeman): These are methods, so handle computed name case
                        if (node.name && subsequentNode.name && node.name.text === subsequentNode.name.text) {
                            var reportError = (node.kind === 147 /* MethodDeclaration */ || node.kind === 146 /* MethodSignature */) &&
                                (node.flags & 32 /* Static */) !== (subsequentNode.flags & 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 = node.flags & 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 (node.flags & 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 === 222 /* InterfaceDeclaration */ || node.parent.kind === 159 /* 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 === 220 /* FunctionDeclaration */ || node.kind === 147 /* MethodDeclaration */ || node.kind === 146 /* MethodSignature */ || node.kind === 148 /* 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(declaration.name, ts.Diagnostics.Duplicate_function_implementation);
                });
            }
            // Abstract methods can't have an implementation -- in particular, they don't need one.
            if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
                !(lastSeenNonAmbientDeclaration.flags & 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_3 = signatures; _a < signatures_3.length; _a++) {
                        var signature = signatures_3[_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.flags & 7340032 /* Export */)) {
                    // 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;
            }
            // we use SymbolFlags.ExportValue, SymbolFlags.ExportType and SymbolFlags.ExportNamespace
            // to denote disjoint declarationSpaces (without making new enum type).
            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);
                    // Only error on the declarations that contributed to the intersecting spaces.
                    if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
                        error(d.name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(d.name));
                    }
                    else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
                        error(d.name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(d.name));
                    }
                }
            }
            function getDeclarationSpaces(d) {
                switch (d.kind) {
                    case 222 /* InterfaceDeclaration */:
                        return 2097152 /* ExportType */;
                    case 225 /* ModuleDeclaration */:
                        return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */
                            ? 4194304 /* ExportNamespace */ | 1048576 /* ExportValue */
                            : 4194304 /* ExportNamespace */;
                    case 221 /* ClassDeclaration */:
                    case 224 /* EnumDeclaration */:
                        return 2097152 /* ExportType */ | 1048576 /* ExportValue */;
                    case 229 /* ImportEqualsDeclaration */:
                        var result_1 = 0;
                        var target = resolveAlias(getSymbolOfNode(d));
                        ts.forEach(target.declarations, function (d) { result_1 |= getDeclarationSpaces(d); });
                        return result_1;
                    default:
                        return 1048576 /* ExportValue */;
                }
            }
        }
        function checkNonThenableType(type, location, message) {
            type = getWidenedType(type);
            if (!isTypeAny(type) && !isTypeNever(type) && isTypeAssignableTo(type, getGlobalThenableType())) {
                if (location) {
                    if (!message) {
                        message = ts.Diagnostics.Operand_for_await_does_not_have_a_valid_callable_then_member;
                    }
                    error(location, message);
                }
                return unknownType;
            }
            return type;
        }
        /**
          * 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 getPromisedType(promise) {
            //
            //  { // promise
            //      then( // thenFunction
            //          onfulfilled: ( // onfulfilledParameterType
            //              value: T // valueParameterType
            //          ) => any
            //      ): any;
            //  }
            //
            if (isTypeAny(promise)) {
                return undefined;
            }
            if (promise.flags & 4096 /* Reference */) {
                if (promise.target === tryGetGlobalPromiseType()
                    || promise.target === getGlobalPromiseLikeType()) {
                    return promise.typeArguments[0];
                }
            }
            var globalPromiseLikeType = getInstantiatedGlobalPromiseLikeType();
            if (globalPromiseLikeType === emptyObjectType || !isTypeAssignableTo(promise, globalPromiseLikeType)) {
                return undefined;
            }
            var thenFunction = getTypeOfPropertyOfType(promise, "then");
            if (!thenFunction || isTypeAny(thenFunction)) {
                return undefined;
            }
            var thenSignatures = getSignaturesOfType(thenFunction, 0 /* Call */);
            if (thenSignatures.length === 0) {
                return undefined;
            }
            var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 131072 /* NEUndefined */);
            if (isTypeAny(onfulfilledParameterType)) {
                return undefined;
            }
            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
            if (onfulfilledParameterSignatures.length === 0) {
                return undefined;
            }
            return getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature));
        }
        function getTypeOfFirstParameterOfSignature(signature) {
            return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType;
        }
        /**
          * 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 getAwaitedType(type) {
            return checkAwaitedType(type, /*location*/ undefined, /*message*/ undefined);
        }
        function checkAwaitedType(type, location, message) {
            return checkAwaitedTypeWorker(type);
            function checkAwaitedTypeWorker(type) {
                if (type.flags & 16384 /* Union */) {
                    var types = [];
                    for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                        var constituentType = _a[_i];
                        types.push(checkAwaitedTypeWorker(constituentType));
                    }
                    return getUnionType(types);
                }
                else {
                    var promisedType = getPromisedType(type);
                    if (promisedType === undefined) {
                        // The type was not a PromiseLike, 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 have been reported in
                        // the call to checkNonThenableType and we will return unknownType.
                        //
                        // An example of a non-promise "thenable" might be:
                        //
                        //  await { then(): void {} }
                        //
                        // The "thenable" does not match the minimal definition for a PromiseLike. 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>.
                        return checkNonThenableType(type, location, message);
                    }
                    else {
                        if (type.id === promisedType.id || ts.indexOf(awaitedTypeStack, promisedType.id) >= 0) {
                            // We have a bad actor in the form of a promise whose promised type is
                            // the same promise type, or a mutually recursive promise. Return the
                            // unknown type 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 (location) {
                                error(location, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method, symbolToString(type.symbol));
                            }
                            return unknownType;
                        }
                        // 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 = checkAwaitedTypeWorker(promisedType);
                        awaitedTypeStack.pop();
                        return awaitedType;
                    }
                }
            }
        }
        /**
         * Checks that the return type provided is an instantiation of the global Promise<T> type
         * and returns the awaited type of the return type.
         *
         * @param returnType The return type of a FunctionLikeDeclaration
         * @param location The node on which to report the error.
         */
        function checkCorrectPromiseType(returnType, location) {
            if (returnType === unknownType) {
                // The return type already had some other error, so we ignore and return
                // the unknown type.
                return unknownType;
            }
            var globalPromiseType = getGlobalPromiseType();
            if (globalPromiseType === emptyGenericType
                || globalPromiseType === getTargetType(returnType)) {
                // Either we couldn't resolve the global promise type, which would have already
                // reported an error, or we could resolve it and the return type is a valid type
                // reference to the global type. In either case, we return the awaited type for
                // the return type.
                return checkAwaitedType(returnType, location, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
            }
            // 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(location, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
            return unknownType;
        }
        /**
          * Checks the return type of an async function to ensure it is a compatible
          * Promise implementation.
          * @param node The signature to check
          * @param returnType The return type for the function
          * @remarks
          * 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.
          */
        function checkAsyncFunctionReturnType(node) {
            if (languageVersion >= 2 /* ES6 */) {
                var returnType = getTypeFromTypeNode(node.type);
                return checkCorrectPromiseType(returnType, node.type);
            }
            var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
            if (globalPromiseConstructorLikeType === emptyObjectType) {
                // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
                // compatibility with __awaiter.
                return unknownType;
            }
            // 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>;
            //  }
            //
            // When we get the type of the `Promise` symbol here, we get the type of the static
            // side of the `Promise` class, which would be `{ new <T>(...): Promise<T> }`.
            var promiseType = getTypeFromTypeNode(node.type);
            if (promiseType === unknownType && compilerOptions.isolatedModules) {
                // If we are compiling with isolatedModules, we may not be able to resolve the
                // type as a value. As such, we will just return unknownType;
                return unknownType;
            }
            var promiseConstructor = getNodeLinks(node.type).resolvedSymbol;
            if (!promiseConstructor || !symbolIsValue(promiseConstructor)) {
                var typeName = promiseConstructor
                    ? symbolToString(promiseConstructor)
                    : typeToString(promiseType);
                error(node, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName);
                return unknownType;
            }
            // If the Promise constructor, resolved locally, is an alias symbol we should mark it as referenced.
            checkReturnTypeAnnotationAsExpression(node);
            // Validate the promise constructor type.
            var promiseConstructorType = getTypeOfSymbol(promiseConstructor);
            if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
                return unknownType;
            }
            // Verify there is no local declaration that could collide with the promise constructor.
            var promiseName = ts.getEntityNameFromTypeNode(node.type);
            var promiseNameOrNamespaceRoot = getFirstIdentifier(promiseName);
            var rootSymbol = getSymbol(node.locals, promiseNameOrNamespaceRoot.text, 107455 /* Value */);
            if (rootSymbol) {
                error(rootSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, promiseNameOrNamespaceRoot.text, getFullyQualifiedName(promiseConstructor));
                return unknownType;
            }
            // Get and return the awaited type of the return type.
            return checkAwaitedType(promiseType, node, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
        }
        /** 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 221 /* ClassDeclaration */:
                    var classSymbol = getSymbolOfNode(node.parent);
                    var classConstructorType = getTypeOfSymbol(classSymbol);
                    expectedReturnType = getUnionType([classConstructorType, voidType]);
                    break;
                case 142 /* 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 145 /* 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 147 /* MethodDeclaration */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                    var methodType = getTypeOfNode(node.parent);
                    var descriptorType = createTypedPropertyDescriptorType(methodType);
                    expectedReturnType = getUnionType([descriptorType, voidType]);
                    break;
            }
            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, errorInfo);
        }
        /** Checks a type reference node as an expression. */
        function checkTypeNodeAsExpression(node) {
            // When we are emitting type metadata for decorators, we need to try to check the type
            // as if it were an expression so that we can emit the type in a value position when we
            // serialize the type metadata.
            if (node && node.kind === 155 /* TypeReference */) {
                var root = getFirstIdentifier(node.typeName);
                var meaning = root.parent.kind === 155 /* TypeReference */ ? 793056 /* Type */ : 1536 /* Namespace */;
                // Resolve type so we know which symbol is referenced
                var rootSymbol = resolveName(root, root.text, meaning | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
                // Resolved symbol is alias
                if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */) {
                    var aliasTarget = resolveAlias(rootSymbol);
                    // If alias has value symbol - mark alias as referenced
                    if (aliasTarget.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
                        markAliasSymbolAsReferenced(rootSymbol);
                    }
                }
            }
        }
        /**
          * Checks the type annotation of an accessor declaration or property declaration as
          * an expression if it is a type reference to a type with a value declaration.
          */
        function checkTypeAnnotationAsExpression(node) {
            checkTypeNodeAsExpression(node.type);
        }
        function checkReturnTypeAnnotationAsExpression(node) {
            checkTypeNodeAsExpression(node.type);
        }
        /** Checks the type annotation of the parameters of a function/method or the constructor of a class as expressions */
        function checkParameterTypeAnnotationsAsExpressions(node) {
            // ensure all type annotations with a value declaration are checked as an expression
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                checkTypeAnnotationAsExpression(parameter);
            }
        }
        /** 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);
            }
            if (compilerOptions.emitDecoratorMetadata) {
                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
                switch (node.kind) {
                    case 221 /* ClassDeclaration */:
                        var constructor = ts.getFirstConstructorWithBody(node);
                        if (constructor) {
                            checkParameterTypeAnnotationsAsExpressions(constructor);
                        }
                        break;
                    case 147 /* MethodDeclaration */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        checkParameterTypeAnnotationsAsExpressions(node);
                        checkReturnTypeAnnotationAsExpression(node);
                        break;
                    case 145 /* PropertyDeclaration */:
                    case 142 /* Parameter */:
                        checkTypeAnnotationAsExpression(node);
                        break;
                }
            }
            ts.forEach(node.decorators, checkDecorator);
        }
        function checkFunctionDeclaration(node) {
            if (produceDiagnostics) {
                checkFunctionOrMethodDeclaration(node) || checkGrammarForGenerator(node);
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function checkFunctionOrMethodDeclaration(node) {
            checkDecorators(node);
            checkSignatureDeclaration(node);
            var isAsync = ts.isAsyncFunctionLike(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 === 140 /* 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.forEach(localSymbol.declarations, 
                // Get first non javascript function declaration
                function (declaration) { return declaration.kind === node.kind && !ts.isSourceFileJavaScript(ts.getSourceFileOfNode(declaration)) ?
                    declaration : undefined; });
                // 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);
            if (!node.asteriskToken) {
                var returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
                checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
            }
            if (produceDiagnostics && !node.type) {
                // 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 (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
                    reportImplicitAnyError(node, anyType);
                }
                if (node.asteriskToken && 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 256 /* SourceFile */:
                        case 225 /* ModuleDeclaration */:
                            checkUnusedModuleMembers(node);
                            break;
                        case 221 /* ClassDeclaration */:
                        case 192 /* ClassExpression */:
                            checkUnusedClassMembers(node);
                            checkUnusedTypeParameters(node);
                            break;
                        case 222 /* InterfaceDeclaration */:
                            checkUnusedTypeParameters(node);
                            break;
                        case 199 /* Block */:
                        case 227 /* CaseBlock */:
                        case 206 /* ForStatement */:
                        case 207 /* ForInStatement */:
                        case 208 /* ForOfStatement */:
                            checkUnusedLocalsAndParameters(node);
                            break;
                        case 148 /* Constructor */:
                        case 179 /* FunctionExpression */:
                        case 220 /* FunctionDeclaration */:
                        case 180 /* ArrowFunction */:
                        case 147 /* MethodDeclaration */:
                        case 149 /* GetAccessor */:
                        case 150 /* SetAccessor */:
                            if (node.body) {
                                checkUnusedLocalsAndParameters(node);
                            }
                            checkUnusedTypeParameters(node);
                            break;
                        case 146 /* MethodSignature */:
                        case 151 /* CallSignature */:
                        case 152 /* ConstructSignature */:
                        case 153 /* IndexSignature */:
                        case 156 /* FunctionType */:
                        case 157 /* ConstructorType */:
                            checkUnusedTypeParameters(node);
                            break;
                    }
                    ;
                }
            }
        }
        function checkUnusedLocalsAndParameters(node) {
            if (node.parent.kind !== 222 /* InterfaceDeclaration */ && noUnusedIdentifiers && !ts.isInAmbientContext(node)) {
                var _loop_1 = function(key) {
                    if (ts.hasProperty(node.locals, key)) {
                        var local_1 = node.locals[key];
                        if (!local_1.isReferenced) {
                            if (local_1.valueDeclaration && local_1.valueDeclaration.kind === 142 /* Parameter */) {
                                var parameter = local_1.valueDeclaration;
                                if (compilerOptions.noUnusedParameters &&
                                    !ts.isParameterPropertyDeclaration(parameter) &&
                                    !parameterIsThisKeyword(parameter) &&
                                    !parameterNameStartsWithUnderscore(parameter)) {
                                    error(local_1.valueDeclaration.name, ts.Diagnostics._0_is_declared_but_never_used, local_1.name);
                                }
                            }
                            else if (compilerOptions.noUnusedLocals) {
                                ts.forEach(local_1.declarations, function (d) { return error(d.name || d, ts.Diagnostics._0_is_declared_but_never_used, local_1.name); });
                            }
                        }
                    }
                };
                for (var key in node.locals) {
                    _loop_1(key);
                }
            }
        }
        function parameterIsThisKeyword(parameter) {
            return parameter.name && parameter.name.originalKeywordKind === 97 /* ThisKeyword */;
        }
        function parameterNameStartsWithUnderscore(parameter) {
            return parameter.name && parameter.name.kind === 69 /* Identifier */ && parameter.name.text.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 === 147 /* MethodDeclaration */ || member.kind === 145 /* PropertyDeclaration */) {
                            if (!member.symbol.isReferenced && member.flags & 8 /* Private */) {
                                error(member.name, ts.Diagnostics._0_is_declared_but_never_used, member.symbol.name);
                            }
                        }
                        else if (member.kind === 148 /* Constructor */) {
                            for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                                var parameter = _c[_b];
                                if (!parameter.symbol.isReferenced && parameter.flags & 8 /* Private */) {
                                    error(parameter.name, ts.Diagnostics._0_is_declared_but_never_used, parameter.symbol.name);
                                }
                            }
                        }
                    }
                }
            }
        }
        function checkUnusedTypeParameters(node) {
            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
                if (node.typeParameters) {
                    for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) {
                        var typeParameter = _a[_i];
                        if (!typeParameter.symbol.isReferenced) {
                            error(typeParameter.name, ts.Diagnostics._0_is_declared_but_never_used, typeParameter.symbol.name);
                        }
                    }
                }
            }
        }
        function checkUnusedModuleMembers(node) {
            if (compilerOptions.noUnusedLocals && !ts.isInAmbientContext(node)) {
                for (var key in node.locals) {
                    if (ts.hasProperty(node.locals, key)) {
                        var local = node.locals[key];
                        if (!local.isReferenced && !local.exportSymbol) {
                            for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) {
                                var declaration = _a[_i];
                                if (!ts.isAmbientModule(declaration)) {
                                    error(declaration.name, ts.Diagnostics._0_is_declared_but_never_used, local.name);
                                }
                            }
                        }
                    }
                }
            }
        }
        function checkBlock(node) {
            // Grammar checking for SyntaxKind.Block
            if (node.kind === 199 /* Block */) {
                checkGrammarStatementInAmbientContext(node);
            }
            ts.forEach(node.statements, checkSourceElement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkCollisionWithArgumentsInGeneratedCode(node) {
            // no rest parameters \ declaration context \ overload - no codegen impact
            if (!ts.hasDeclaredRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) {
                return;
            }
            ts.forEach(node.parameters, function (p) {
                if (p.name && !ts.isBindingPattern(p.name) && p.name.text === argumentsSymbol.name) {
                    error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
                }
            });
        }
        function needCollisionCheckForIdentifier(node, identifier, name) {
            if (!(identifier && identifier.text === name)) {
                return false;
            }
            if (node.kind === 145 /* PropertyDeclaration */ ||
                node.kind === 144 /* PropertySignature */ ||
                node.kind === 147 /* MethodDeclaration */ ||
                node.kind === 146 /* MethodSignature */ ||
                node.kind === 149 /* GetAccessor */ ||
                node.kind === 150 /* 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 === 142 /* 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);
            }
        }
        // this function will run after checking the source file so 'CaptureThis' is correct for all nodes
        function checkIfThisIsCapturedInEnclosingScope(node) {
            var current = node;
            while (current) {
                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                    var isDeclaration_1 = node.kind !== 69 /* Identifier */;
                    if (isDeclaration_1) {
                        error(node.name, 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;
                }
                current = current.parent;
            }
        }
        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_2 = node.kind !== 69 /* Identifier */;
                if (isDeclaration_2) {
                    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) {
            if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (node.kind === 225 /* 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 === 256 /* 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 (!needCollisionCheckForIdentifier(node, name, "Promise")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (node.kind === 225 /* 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 === 256 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 2097152 /* 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) & 3072 /* 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 === 218 /* VariableDeclaration */ && !node.initializer) {
                return;
            }
            var symbol = getSymbolOfNode(node);
            if (symbol.flags & 1 /* FunctionScopedVariable */) {
                var localDeclarationSymbol = resolveName(node, node.name.text, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
                if (localDeclarationSymbol &&
                    localDeclarationSymbol !== symbol &&
                    localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
                    if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & 3072 /* BlockScoped */) {
                        var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 219 /* VariableDeclarationList */);
                        var container = varDeclList.parent.kind === 200 /* 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 === 199 /* Block */ && ts.isFunctionLike(container.parent) ||
                                container.kind === 226 /* ModuleBlock */ ||
                                container.kind === 225 /* ModuleDeclaration */ ||
                                container.kind === 256 /* 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_17 = symbolToString(localDeclarationSymbol);
                            error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_17, name_17);
                        }
                    }
                }
            }
        }
        // Check that a parameter initializer contains no references to parameters declared to the right of itself
        function checkParameterInitializer(node) {
            if (ts.getRootDeclaration(node).kind !== 142 /* 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 === 172 /* PropertyAccessExpression */) {
                    // skip property names in property access expression
                    return visit(n.expression);
                }
                else if (n.kind === 69 /* Identifier */) {
                    // check FunctionLikeDeclaration.locals (stores parameters\function local variable)
                    // if it contains entry with a specified name
                    var symbol = resolveName(n, n.text, 107455 /* Value */ | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
                    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 === 142 /* Parameter */) {
                            // 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
                            var current = n;
                            while (current !== node.initializer) {
                                if (ts.isFunctionLike(current.parent)) {
                                    return;
                                }
                                // computed property names/initializers in instance property declaration of class like entities
                                // are executed in constructor and thus deferred
                                if (current.parent.kind === 145 /* PropertyDeclaration */ &&
                                    !(current.parent.flags & 32 /* Static */) &&
                                    ts.isClassLike(current.parent.parent)) {
                                    return;
                                }
                                current = current.parent;
                            }
                        }
                        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);
                }
            }
        }
        // Check variable, parameter, or property declaration
        function checkVariableLikeDeclaration(node) {
            checkDecorators(node);
            checkSourceElement(node.type);
            // 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 === 140 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
                if (node.initializer) {
                    checkExpressionCached(node.initializer);
                }
            }
            if (node.kind === 169 /* BindingElement */) {
                // check computed properties inside property names of binding elements
                if (node.propertyName && node.propertyName.kind === 140 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.propertyName);
                }
                // check private/protected variable access
                var parent_11 = node.parent.parent;
                var parentType = getTypeForBindingElementParent(parent_11);
                var name_18 = node.propertyName || node.name;
                var property = getPropertyOfType(parentType, getTextOfPropertyName(name_18));
                if (parent_11.initializer && property && getParentOfSymbol(property)) {
                    checkClassPropertyAccess(parent_11, parent_11.initializer, parentType, property);
                }
            }
            // For a binding pattern, check contained binding elements
            if (ts.isBindingPattern(node.name)) {
                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 === 142 /* 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 !== 207 /* ForInStatement */) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
                    checkParameterInitializer(node);
                }
                return;
            }
            var symbol = getSymbolOfNode(node);
            var type = 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 !== 207 /* 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 = 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(symbol.valueDeclaration.name, 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 !== 145 /* PropertyDeclaration */ && node.kind !== 144 /* PropertySignature */) {
                // We know we don't have a binding pattern or computed name here
                checkExportsOnMergedDeclarations(node);
                if (node.kind === 218 /* VariableDeclaration */ || node.kind === 169 /* BindingElement */) {
                    checkVarDeclaredNamesNotShadowed(node);
                }
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function areDeclarationFlagsIdentical(left, right) {
            if ((left.kind === 142 /* Parameter */ && right.kind === 218 /* VariableDeclaration */) ||
                (left.kind === 218 /* VariableDeclaration */ && right.kind === 142 /* 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 (left.flags & interestingFlags) === (right.flags & 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 === 171 /* ObjectLiteralExpression */) {
                if (ts.isAsyncFunctionLike(node)) {
                    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 === 201 /* 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 === 219 /* VariableDeclarationList */) {
                    checkGrammarVariableDeclarationList(node.initializer);
                }
            }
            if (node.initializer) {
                if (node.initializer.kind === 219 /* 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);
            // 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 === 219 /* VariableDeclarationList */) {
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                var varExpr = node.initializer;
                var iteratedType = checkRightHandSideOfForOf(node.expression);
                // There may be a destructuring assignment on the left side
                if (varExpr.kind === 170 /* ArrayLiteralExpression */ || varExpr.kind === 171 /* 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, /*invalidReferenceMessage*/ ts.Diagnostics.Invalid_left_hand_side_in_for_of_statement, 
                    /*constantVariableMessage*/ ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_be_a_constant_or_a_read_only_property);
                    // 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);
            // 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 === 219 /* 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 === 170 /* ArrayLiteralExpression */ || varExpr.kind === 171 /* ObjectLiteralExpression */) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, 258 /* StringLike */)) {
                    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.Invalid_left_hand_side_in_for_in_statement, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_constant_or_a_read_only_property);
                }
            }
            var rightType = checkNonNullExpression(node.expression);
            // 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 (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 80896 /* ObjectType */ | 512 /* TypeParameter */)) {
                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) {
            var expressionType = checkNonNullExpression(rhsExpression);
            return checkIteratedTypeOrElementType(expressionType, rhsExpression, /*allowStringInput*/ true);
        }
        function checkIteratedTypeOrElementType(inputType, errorNode, allowStringInput) {
            if (isTypeAny(inputType)) {
                return inputType;
            }
            if (languageVersion >= 2 /* ES6 */) {
                return checkElementTypeOfIterable(inputType, errorNode);
            }
            if (allowStringInput) {
                return checkElementTypeOfArrayOrString(inputType, errorNode);
            }
            if (isArrayLikeType(inputType)) {
                var indexType = getIndexTypeOfType(inputType, 1 /* Number */);
                if (indexType) {
                    return indexType;
                }
            }
            if (errorNode) {
                error(errorNode, ts.Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType));
            }
            return unknownType;
        }
        /**
         * When errorNode is undefined, it means we should not report any errors.
         */
        function checkElementTypeOfIterable(iterable, errorNode) {
            var elementType = getElementTypeOfIterable(iterable, errorNode);
            // Now even though we have extracted the iteratedType, we will have to validate that the type
            // passed in is actually an Iterable.
            if (errorNode && elementType) {
                checkTypeAssignableTo(iterable, createIterableType(elementType), errorNode);
            }
            return elementType || anyType;
        }
        /**
         * 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]: { // iteratorFunction
         *         (): Iterator<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'.
         */
        function getElementTypeOfIterable(type, errorNode) {
            if (isTypeAny(type)) {
                return undefined;
            }
            var typeAsIterable = type;
            if (!typeAsIterable.iterableElementType) {
                // As an optimization, if the type is instantiated directly using the globalIterableType (Iterable<number>),
                // then just grab its type argument.
                if ((type.flags & 4096 /* Reference */) && type.target === getGlobalIterableType()) {
                    typeAsIterable.iterableElementType = type.typeArguments[0];
                }
                else {
                    var iteratorFunction = getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator"));
                    if (isTypeAny(iteratorFunction)) {
                        return undefined;
                    }
                    var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0 /* Call */) : emptyArray;
                    if (iteratorFunctionSignatures.length === 0) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
                        }
                        return undefined;
                    }
                    typeAsIterable.iterableElementType = getElementTypeOfIterator(getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)), errorNode);
                }
            }
            return typeAsIterable.iterableElementType;
        }
        /**
         * This function has very similar logic as getElementTypeOfIterable, except that it operates on
         * Iterators instead of Iterables. Here is the structure:
         *
         *  { // iterator
         *      next: { // iteratorNextFunction
         *          (): { // iteratorNextResult
         *              value: T // iteratorNextValue
         *          }
         *      }
         *  }
         *
         */
        function getElementTypeOfIterator(type, errorNode) {
            if (isTypeAny(type)) {
                return undefined;
            }
            var typeAsIterator = type;
            if (!typeAsIterator.iteratorElementType) {
                // As an optimization, if the type is instantiated directly using the globalIteratorType (Iterator<number>),
                // then just grab its type argument.
                if ((type.flags & 4096 /* Reference */) && type.target === getGlobalIteratorType()) {
                    typeAsIterator.iteratorElementType = type.typeArguments[0];
                }
                else {
                    var iteratorNextFunction = getTypeOfPropertyOfType(type, "next");
                    if (isTypeAny(iteratorNextFunction)) {
                        return undefined;
                    }
                    var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0 /* Call */) : emptyArray;
                    if (iteratorNextFunctionSignatures.length === 0) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method);
                        }
                        return undefined;
                    }
                    var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature));
                    if (isTypeAny(iteratorNextResult)) {
                        return undefined;
                    }
                    var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value");
                    if (!iteratorNextValue) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property);
                        }
                        return undefined;
                    }
                    typeAsIterator.iteratorElementType = iteratorNextValue;
                }
            }
            return typeAsIterator.iteratorElementType;
        }
        function getElementTypeOfIterableIterator(type) {
            if (isTypeAny(type)) {
                return undefined;
            }
            // As an optimization, if the type is instantiated directly using the globalIterableIteratorType (IterableIterator<number>),
            // then just grab its type argument.
            if ((type.flags & 4096 /* Reference */) && type.target === getGlobalIterableIteratorType()) {
                return type.typeArguments[0];
            }
            return getElementTypeOfIterable(type, /*errorNode*/ undefined) ||
                getElementTypeOfIterator(type, /*errorNode*/ undefined);
        }
        /**
         * This function does the following steps:
         *   1. Break up arrayOrStringType (possibly a union) into its string constituents and array constituents.
         *   2. Take the element types of the array constituents.
         *   3. Return the union of the element types, and string if there was a string constituent.
         *
         * For example:
         *     string -> string
         *     number[] -> number
         *     string[] | number[] -> string | number
         *     string | number[] -> string | number
         *     string | string[] | number[] -> string | number
         *
         * It also errors if:
         *   1. Some constituent is neither a string nor an array.
         *   2. Some constituent is a string and target is less than ES5 (because in ES3 string is not indexable).
         */
        function checkElementTypeOfArrayOrString(arrayOrStringType, errorNode) {
            ts.Debug.assert(languageVersion < 2 /* ES6 */);
            // After we remove all types that are StringLike, we will know if there was a string constituent
            // based on whether the remaining type is the same as the initial type.
            var arrayType = arrayOrStringType;
            if (arrayOrStringType.flags & 16384 /* Union */) {
                arrayType = getUnionType(ts.filter(arrayOrStringType.types, function (t) { return !(t.flags & 258 /* StringLike */); }));
            }
            else if (arrayOrStringType.flags & 258 /* StringLike */) {
                arrayType = neverType;
            }
            var hasStringConstituent = arrayOrStringType !== arrayType;
            var reportedError = false;
            if (hasStringConstituent) {
                if (languageVersion < 1 /* ES5 */) {
                    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 === neverType) {
                    return stringType;
                }
            }
            if (!isArrayLikeType(arrayType)) {
                if (!reportedError) {
                    // Which error we report depends on whether 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, we want to say that number is not an array type
                    // or a string type.
                    var diagnostic = hasStringConstituent
                        ? ts.Diagnostics.Type_0_is_not_an_array_type
                        : ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
                    error(errorNode, diagnostic, typeToString(arrayType));
                }
                return hasStringConstituent ? stringType : unknownType;
            }
            var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */) || unknownType;
            if (hasStringConstituent) {
                // This is just an optimization for the case where arrayOrStringType is string | string[]
                if (arrayElementType.flags & 258 /* StringLike */) {
                    return stringType;
                }
                return getUnionType([arrayElementType, stringType]);
            }
            return arrayElementType;
        }
        function checkBreakOrContinueStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
            // TODO: Check that target label is valid
        }
        function isGetAccessorWithAnnotatedSetAccessor(node) {
            return !!(node.kind === 149 /* GetAccessor */ && ts.getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(node.symbol, 150 /* SetAccessor */)));
        }
        function isUnwrappedReturnTypeVoidOrAny(func, returnType) {
            var unwrappedReturnType = ts.isAsyncFunctionLike(func) ? getPromisedType(returnType) : returnType;
            return unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 16 /* 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 === neverType) {
                    var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
                    if (func.asteriskToken) {
                        // 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 === 150 /* SetAccessor */) {
                        if (node.expression) {
                            error(node.expression, ts.Diagnostics.Setters_cannot_return_a_value);
                        }
                    }
                    else if (func.kind === 148 /* Constructor */) {
                        if (node.expression && !checkTypeAssignableTo(exprType, returnType, node.expression)) {
                            error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
                        }
                    }
                    else if (func.type || isGetAccessorWithAnnotatedSetAccessor(func)) {
                        if (ts.isAsyncFunctionLike(func)) {
                            var promisedType = getPromisedType(returnType);
                            var awaitedType = checkAwaitedType(exprType, node.expression || node, ts.Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_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.expression || node);
                            }
                        }
                        else {
                            checkTypeAssignableTo(exprType, returnType, node.expression || node);
                        }
                    }
                }
                else if (func.kind !== 148 /* 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 & 33554432 /* AwaitContext */) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
                }
            }
            checkExpression(node.expression);
            error(node.expression, ts.Diagnostics.All_symbols_within_a_with_block_will_be_resolved_to_any);
        }
        function checkSwitchStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var firstDefaultClause;
            var hasDuplicateDefaultClause = false;
            var expressionType = checkExpression(node.expression);
            ts.forEach(node.caseBlock.clauses, function (clause) {
                // Grammar check for duplicate default clauses, skip if we already report duplicate default clause
                if (clause.kind === 250 /* 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 === 249 /* 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);
                    if (!isTypeEqualityComparableTo(expressionType, caseType)) {
                        // expressionType is not comparable to caseType, try the reversed check and report errors if it fails
                        checkTypeComparableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
                    }
                }
                ts.forEach(clause.statements, checkSourceElement);
            });
            if (node.caseBlock.locals) {
                registerForUnusedIdentifiersCheck(node.caseBlock);
            }
        }
        function checkLabeledStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                var current = node.parent;
                while (current) {
                    if (ts.isFunctionLike(current)) {
                        break;
                    }
                    if (current.kind === 214 /* LabeledStatement */ && current.label.text === node.label.text) {
                        var sourceFile = ts.getSourceFileOfNode(node);
                        grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNodeFromSourceText(sourceFile.text, node.label));
                        break;
                    }
                    current = current.parent;
                }
            }
            // 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.name.kind !== 69 /* Identifier */) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.name, ts.Diagnostics.Catch_clause_variable_name_must_be_an_identifier);
                    }
                    else 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 identifierName = catchClause.variableDeclaration.name.text;
                        var locals = catchClause.block.locals;
                        if (locals && ts.hasProperty(locals, identifierName)) {
                            var localSymbol = locals[identifierName];
                            if (localSymbol && (localSymbol.flags & 2 /* BlockScopedVariable */) !== 0) {
                                grammarErrorOnNode(localSymbol.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, identifierName);
                            }
                        }
                    }
                }
                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 (type.flags & 1024 /* 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 (!(member.flags & 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 && (type.flags & 2048 /* 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;
                }
                // index is numeric and property name is not valid numeric literal
                if (indexKind === 1 /* Number */ && !isNumericName(prop.valueDeclaration.name)) {
                    return;
                }
                // perform property check if property or indexer is declared in 'type'
                // this allows to rule out cases when both property and indexer are inherited from the base class
                var errorNode;
                if (prop.valueDeclaration.name.kind === 140 /* ComputedPropertyName */ || prop.parent === containingType.symbol) {
                    errorNode = prop.valueDeclaration;
                }
                else if (indexDeclaration) {
                    errorNode = indexDeclaration;
                }
                else if (containingType.flags & 2048 /* 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.name) && 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.text) {
                case "any":
                case "number":
                case "boolean":
                case "string":
                case "symbol":
                case "void":
                    error(name, message, name.text);
            }
        }
        /** Check each type parameter and check that type parameters have no duplicate type parameter declarations */
        function checkTypeParameters(typeParameterDeclarations) {
            if (typeParameterDeclarations) {
                for (var i = 0, n = typeParameterDeclarations.length; i < n; i++) {
                    var node = typeParameterDeclarations[i];
                    checkTypeParameter(node);
                    if (produceDiagnostics) {
                        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(node, symbol) {
            if (symbol.declarations.length === 1) {
                return;
            }
            var firstDecl;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 221 /* ClassDeclaration */ || declaration.kind === 222 /* InterfaceDeclaration */) {
                    if (!firstDecl) {
                        firstDecl = declaration;
                    }
                    else if (!areTypeParametersIdentical(firstDecl.typeParameters, node.typeParameters)) {
                        error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, node.name.text);
                    }
                }
            }
        }
        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 && !(node.flags & 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) {
            checkGrammarClassDeclarationHeritageClauses(node);
            checkDecorators(node);
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
                checkCollisionWithCapturedThisVariable(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(node, symbol);
            checkClassForDuplicateDeclarations(node);
            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
            if (baseTypeNode) {
                var baseTypes = getBaseTypes(type);
                if (baseTypes.length && produceDiagnostics) {
                    var baseType_1 = baseTypes[0];
                    var staticBaseType = getBaseConstructorTypeOfClass(type);
                    checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
                    checkSourceElement(baseTypeNode.expression);
                    if (baseTypeNode.typeArguments) {
                        ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                        for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments); _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 (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */)) {
                        // 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);
                        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.isSupportedExpressionWithTypeArguments(typeRefNode)) {
                        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) {
                            var declaredType = (t.flags & 4096 /* Reference */) ? t.target : t;
                            if (declaredType.flags & (1024 /* Class */ | 2048 /* Interface */)) {
                                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 && declaration.flags & 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, node.expression.text);
                    }
                }
            }
        }
        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 s.flags & 16777216 /* Instantiated */ ? getSymbolLinks(s).target : s;
        }
        function getClassLikeDeclarationOfSymbol(symbol) {
            return ts.forEach(symbol.declarations, function (d) { return ts.isClassLike(d) ? d : undefined; });
        }
        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 = getPropertiesOfObjectType(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 & 134217728 /* Prototype */) {
                    continue;
                }
                var derived = getTargetSymbol(getPropertyOfObjectType(type, base.name));
                var baseDeclarationFlags = getDeclarationFlagsFromSymbol(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 || !(derivedClassDecl.flags & 128 /* Abstract */))) {
                            if (derivedClassDecl.kind === 192 /* 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 = getDeclarationFlagsFromSymbol(derived);
                        if ((baseDeclarationFlags & 8 /* Private */) || (derivedDeclarationFlags & 8 /* Private */)) {
                            // either base or derived property is private - not override, skip it
                            continue;
                        }
                        if ((baseDeclarationFlags & 32 /* Static */) !== (derivedDeclarationFlags & 32 /* Static */)) {
                            // value of 'static' is not the same for properties - not override, skip it
                            continue;
                        }
                        if ((base.flags & derived.flags & 8192 /* Method */) || ((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 (base.flags & 8192 /* Method */) {
                            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 {
                                ts.Debug.assert((derived.flags & 4 /* Property */) !== 0);
                                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 */) {
                            ts.Debug.assert((derived.flags & 8192 /* Method */) !== 0);
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                        }
                        else {
                            ts.Debug.assert((base.flags & 98304 /* Accessor */) !== 0);
                            ts.Debug.assert((derived.flags & 8192 /* Method */) !== 0);
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                        }
                        error(derived.valueDeclaration.name, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
                    }
                }
            }
        }
        function isAccessor(kind) {
            return kind === 149 /* GetAccessor */ || kind === 150 /* SetAccessor */;
        }
        function areTypeParametersIdentical(list1, list2) {
            if (!list1 && !list2) {
                return true;
            }
            if (!list1 || !list2 || list1.length !== list2.length) {
                return false;
            }
            // TypeScript 1.0 spec (April 2014):
            // When a generic interface has multiple declarations,  all declarations must have identical type parameter
            // lists, i.e. identical type parameter names with identical constraints in identical order.
            for (var i = 0, len = list1.length; i < len; i++) {
                var tp1 = list1[i];
                var tp2 = list2[i];
                if (tp1.name.text !== tp2.name.text) {
                    return false;
                }
                if (!tp1.constraint && !tp2.constraint) {
                    continue;
                }
                if (!tp1.constraint || !tp2.constraint) {
                    return false;
                }
                if (!isTypeIdenticalTo(getTypeFromTypeNode(tp1.constraint), getTypeFromTypeNode(tp2.constraint))) {
                    return false;
                }
            }
            return true;
        }
        function checkInheritedPropertiesAreIdentical(type, typeNode) {
            var baseTypes = getBaseTypes(type);
            if (baseTypes.length < 2) {
                return true;
            }
            var seen = {};
            ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen[p.name] = { 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 = getPropertiesOfObjectType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_4 = properties; _a < properties_4.length; _a++) {
                    var prop = properties_4[_a];
                    if (!ts.hasProperty(seen, prop.name)) {
                        seen[prop.name] = { prop: prop, containingType: base };
                    }
                    else {
                        var existing = seen[prop.name];
                        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(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(node, symbol);
                // Only check this symbol once
                var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 222 /* 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.isSupportedExpressionWithTypeArguments(heritageElement)) {
                    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);
                checkUnusedTypeParameters(node);
            }
        }
        function checkTypeAliasDeclaration(node) {
            // Grammar checking
            checkGrammarDecorators(node) || checkGrammarModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            checkSourceElement(node.type);
        }
        function computeEnumMemberValues(node) {
            var nodeLinks = getNodeLinks(node);
            if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) {
                var enumSymbol = getSymbolOfNode(node);
                var enumType = getDeclaredTypeOfSymbol(enumSymbol);
                var autoValue = 0; // set to undefined when enum member is non-constant
                var ambient = ts.isInAmbientContext(node);
                var enumIsConst = ts.isConst(node);
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    if (isComputedNonLiteralName(member.name)) {
                        error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
                    }
                    else {
                        var text = getTextOfPropertyName(member.name);
                        if (isNumericLiteralName(text)) {
                            error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
                        }
                    }
                    var previousEnumMemberIsNonConstant = autoValue === undefined;
                    var initializer = member.initializer;
                    if (initializer) {
                        autoValue = computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient);
                    }
                    else if (ambient && !enumIsConst) {
                        // 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 assigned).
                        autoValue = undefined;
                    }
                    else if (previousEnumMemberIsNonConstant) {
                        // 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
                        error(member.name, ts.Diagnostics.Enum_member_must_have_initializer);
                    }
                    if (autoValue !== undefined) {
                        getNodeLinks(member).enumMemberValue = autoValue;
                        autoValue++;
                    }
                }
                nodeLinks.flags |= 16384 /* EnumValuesComputed */;
            }
            function computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient) {
                // Controls if error should be reported after evaluation of constant value is completed
                // Can be false if another more precise error was already reported during evaluation.
                var reportError = true;
                var value = evalConstant(initializer);
                if (reportError) {
                    if (value === undefined) {
                        if (enumIsConst) {
                            error(initializer, ts.Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
                        }
                        else if (ambient) {
                            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), enumType, initializer, /*headMessage*/ undefined);
                        }
                    }
                    else if (enumIsConst) {
                        if (isNaN(value)) {
                            error(initializer, ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN);
                        }
                        else if (!isFinite(value)) {
                            error(initializer, ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
                        }
                    }
                }
                return value;
                function evalConstant(e) {
                    switch (e.kind) {
                        case 185 /* PrefixUnaryExpression */:
                            var value_1 = evalConstant(e.operand);
                            if (value_1 === undefined) {
                                return undefined;
                            }
                            switch (e.operator) {
                                case 35 /* PlusToken */: return value_1;
                                case 36 /* MinusToken */: return -value_1;
                                case 50 /* TildeToken */: return ~value_1;
                            }
                            return undefined;
                        case 187 /* BinaryExpression */:
                            var left = evalConstant(e.left);
                            if (left === undefined) {
                                return undefined;
                            }
                            var right = evalConstant(e.right);
                            if (right === undefined) {
                                return undefined;
                            }
                            switch (e.operatorToken.kind) {
                                case 47 /* BarToken */: return left | right;
                                case 46 /* AmpersandToken */: return left & right;
                                case 44 /* GreaterThanGreaterThanToken */: return left >> right;
                                case 45 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
                                case 43 /* LessThanLessThanToken */: return left << right;
                                case 48 /* CaretToken */: return left ^ right;
                                case 37 /* AsteriskToken */: return left * right;
                                case 39 /* SlashToken */: return left / right;
                                case 35 /* PlusToken */: return left + right;
                                case 36 /* MinusToken */: return left - right;
                                case 40 /* PercentToken */: return left % right;
                            }
                            return undefined;
                        case 8 /* NumericLiteral */:
                            return +e.text;
                        case 178 /* ParenthesizedExpression */:
                            return evalConstant(e.expression);
                        case 69 /* Identifier */:
                        case 173 /* ElementAccessExpression */:
                        case 172 /* PropertyAccessExpression */:
                            var member = initializer.parent;
                            var currentType = getTypeOfSymbol(getSymbolOfNode(member.parent));
                            var enumType_1;
                            var propertyName = void 0;
                            if (e.kind === 69 /* Identifier */) {
                                // unqualified names can refer to member that reside in different declaration of the enum so just doing name resolution won't work.
                                // instead pick current enum type and later try to fetch member from the type
                                enumType_1 = currentType;
                                propertyName = e.text;
                            }
                            else {
                                var expression = void 0;
                                if (e.kind === 173 /* ElementAccessExpression */) {
                                    if (e.argumentExpression === undefined ||
                                        e.argumentExpression.kind !== 9 /* StringLiteral */) {
                                        return undefined;
                                    }
                                    expression = e.expression;
                                    propertyName = e.argumentExpression.text;
                                }
                                else {
                                    expression = e.expression;
                                    propertyName = e.name.text;
                                }
                                // expression part in ElementAccess\PropertyAccess should be either identifier or dottedName
                                var current = expression;
                                while (current) {
                                    if (current.kind === 69 /* Identifier */) {
                                        break;
                                    }
                                    else if (current.kind === 172 /* PropertyAccessExpression */) {
                                        current = current.expression;
                                    }
                                    else {
                                        return undefined;
                                    }
                                }
                                enumType_1 = checkExpression(expression);
                                // allow references to constant members of other enums
                                if (!(enumType_1.symbol && (enumType_1.symbol.flags & 384 /* Enum */))) {
                                    return undefined;
                                }
                            }
                            if (propertyName === undefined) {
                                return undefined;
                            }
                            var property = getPropertyOfObjectType(enumType_1, propertyName);
                            if (!property || !(property.flags & 8 /* EnumMember */)) {
                                return undefined;
                            }
                            var propertyDecl = property.valueDeclaration;
                            // self references are illegal
                            if (member === propertyDecl) {
                                return undefined;
                            }
                            // illegal case: forward reference
                            if (!isBlockScopedNameDeclaredBeforeUse(propertyDecl, member)) {
                                reportError = false;
                                error(e, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
                                return undefined;
                            }
                            return getNodeLinks(propertyDecl).enumMemberValue;
                    }
                }
            }
        }
        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);
            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(decl.name, 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 !== 224 /* 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_5 = declarations; _i < declarations_5.length; _i++) {
                var declaration = declarations_5[_i];
                if ((declaration.kind === 221 /* ClassDeclaration */ ||
                    (declaration.kind === 220 /* 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);
                    }
                }
                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
                    && ts.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, 221 /* 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 /* Merged */);
                        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(node.name.text)) {
                            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 (compilerOptions.noImplicitAny && !node.body) {
                // Ambient shorthand module is an implicit any
                reportImplicitAnyError(node, anyType);
            }
            if (node.body) {
                checkSourceElement(node.body);
                if (!ts.isGlobalScopeAugmentation(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkModuleAugmentationElement(node, isGlobalAugmentation) {
            switch (node.kind) {
                case 200 /* 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 235 /* ExportAssignment */:
                case 236 /* ExportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations);
                    break;
                case 229 /* ImportEqualsDeclaration */:
                case 230 /* ImportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module);
                    break;
                case 169 /* BindingElement */:
                case 218 /* VariableDeclaration */:
                    var name_19 = node.name;
                    if (ts.isBindingPattern(name_19)) {
                        for (var _b = 0, _c = name_19.elements; _b < _c.length; _b++) {
                            var el = _c[_b];
                            // mark individual names in binding pattern
                            checkModuleAugmentationElement(el, isGlobalAugmentation);
                        }
                        break;
                    }
                // fallthrough
                case 221 /* ClassDeclaration */:
                case 224 /* EnumDeclaration */:
                case 220 /* FunctionDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 225 /* ModuleDeclaration */:
                case 223 /* 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 /* Merged */);
                        if (!reportError) {
                            // symbol should not originate in augmentation
                            reportError = ts.isExternalModuleAugmentation(symbol.parent.declarations[0]);
                        }
                    }
                    break;
            }
        }
        function getFirstIdentifier(node) {
            while (true) {
                if (node.kind === 139 /* QualifiedName */) {
                    node = node.left;
                }
                else if (node.kind === 172 /* PropertyAccessExpression */) {
                    node = node.expression;
                }
                else {
                    break;
                }
            }
            ts.Debug.assert(node.kind === 69 /* 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 === 226 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
            if (node.parent.kind !== 256 /* SourceFile */ && !inAmbientExternalModule) {
                error(moduleName, node.kind === 236 /* 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(moduleName.text)) {
                // 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 & 793056 /* Type */ ? 793056 /* Type */ : 0) |
                    (symbol.flags & 1536 /* Namespace */ ? 1536 /* Namespace */ : 0);
                if (target.flags & excludedMeanings) {
                    var message = node.kind === 238 /* 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));
                }
            }
        }
        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) && (node.flags & 1023 /* Modifier */)) {
                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 === 232 /* 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 (node.flags & 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 */ | 1536 /* Namespace */).flags & 1536 /* Namespace */)) {
                                error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
                            }
                        }
                        if (target.flags & 793056 /* Type */) {
                            checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
                        }
                    }
                }
                else {
                    if (modulekind === ts.ModuleKind.ES6 && !ts.isInAmbientContext(node)) {
                        // Import equals declaration is deprecated in es6 or above
                        grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_2015_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) && (node.flags & 1023 /* Modifier */)) {
                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 === 226 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
                    if (node.parent.kind !== 256 /* SourceFile */ && !inAmbientExternalModule) {
                        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));
                    }
                }
            }
        }
        function checkGrammarModuleElementContext(node, errorMessage) {
            if (node.parent.kind !== 256 /* SourceFile */ && node.parent.kind !== 226 /* ModuleBlock */ && node.parent.kind !== 225 /* ModuleDeclaration */) {
                return grammarErrorOnFirstToken(node, errorMessage);
            }
        }
        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.text, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */ | 8388608 /* Alias */, 
                /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
                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, exportedName.text);
                }
                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 === 256 /* SourceFile */ ? node.parent : node.parent.parent;
            if (container.kind === 225 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
                return;
            }
            // Grammar checking
            if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & 1023 /* Modifier */)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
            }
            if (node.expression.kind === 69 /* Identifier */) {
                markExportAsReferenced(node);
            }
            else {
                checkExpressionCached(node.expression);
            }
            checkExternalModuleExports(container);
            if (node.isExportEquals && !ts.isInAmbientContext(node)) {
                if (modulekind === ts.ModuleKind.ES6) {
                    // export assignment is not supported in es6 modules
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_2015_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) {
            for (var id in moduleSymbol.exports) {
                if (id !== "export=") {
                    return true;
                }
            }
            return false;
        }
        function checkExternalModuleExports(node) {
            var moduleSymbol = getSymbolOfNode(node);
            var links = getSymbolLinks(moduleSymbol);
            if (!links.exportsChecked) {
                var exportEqualsSymbol = moduleSymbol.exports["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);
                for (var id in exports) {
                    if (id === "__export") {
                        continue;
                    }
                    var _a = exports[id], declarations = _a.declarations, flags = _a.flags;
                    // 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 & (1536 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) {
                        continue;
                    }
                    var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverload);
                    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)
                        continue;
                    }
                    if (exportedDeclarationsCount > 1) {
                        for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) {
                            var declaration = declarations_6[_i];
                            if (isNotOverload(declaration)) {
                                diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, id));
                            }
                        }
                    }
                }
                links.exportsChecked = true;
            }
            function isNotOverload(declaration) {
                return declaration.kind !== 220 /* FunctionDeclaration */ || !!declaration.body;
            }
        }
        function checkSourceElement(node) {
            if (!node) {
                return;
            }
            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 225 /* ModuleDeclaration */:
                    case 221 /* ClassDeclaration */:
                    case 222 /* InterfaceDeclaration */:
                    case 220 /* FunctionDeclaration */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            switch (kind) {
                case 141 /* TypeParameter */:
                    return checkTypeParameter(node);
                case 142 /* Parameter */:
                    return checkParameter(node);
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                    return checkPropertyDeclaration(node);
                case 156 /* FunctionType */:
                case 157 /* ConstructorType */:
                case 151 /* CallSignature */:
                case 152 /* ConstructSignature */:
                    return checkSignatureDeclaration(node);
                case 153 /* IndexSignature */:
                    return checkSignatureDeclaration(node);
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                    return checkMethodDeclaration(node);
                case 148 /* Constructor */:
                    return checkConstructorDeclaration(node);
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                    return checkAccessorDeclaration(node);
                case 155 /* TypeReference */:
                    return checkTypeReferenceNode(node);
                case 154 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 158 /* TypeQuery */:
                    return checkTypeQuery(node);
                case 159 /* TypeLiteral */:
                    return checkTypeLiteral(node);
                case 160 /* ArrayType */:
                    return checkArrayType(node);
                case 161 /* TupleType */:
                    return checkTupleType(node);
                case 162 /* UnionType */:
                case 163 /* IntersectionType */:
                    return checkUnionOrIntersectionType(node);
                case 164 /* ParenthesizedType */:
                    return checkSourceElement(node.type);
                case 220 /* FunctionDeclaration */:
                    return checkFunctionDeclaration(node);
                case 199 /* Block */:
                case 226 /* ModuleBlock */:
                    return checkBlock(node);
                case 200 /* VariableStatement */:
                    return checkVariableStatement(node);
                case 202 /* ExpressionStatement */:
                    return checkExpressionStatement(node);
                case 203 /* IfStatement */:
                    return checkIfStatement(node);
                case 204 /* DoStatement */:
                    return checkDoStatement(node);
                case 205 /* WhileStatement */:
                    return checkWhileStatement(node);
                case 206 /* ForStatement */:
                    return checkForStatement(node);
                case 207 /* ForInStatement */:
                    return checkForInStatement(node);
                case 208 /* ForOfStatement */:
                    return checkForOfStatement(node);
                case 209 /* ContinueStatement */:
                case 210 /* BreakStatement */:
                    return checkBreakOrContinueStatement(node);
                case 211 /* ReturnStatement */:
                    return checkReturnStatement(node);
                case 212 /* WithStatement */:
                    return checkWithStatement(node);
                case 213 /* SwitchStatement */:
                    return checkSwitchStatement(node);
                case 214 /* LabeledStatement */:
                    return checkLabeledStatement(node);
                case 215 /* ThrowStatement */:
                    return checkThrowStatement(node);
                case 216 /* TryStatement */:
                    return checkTryStatement(node);
                case 218 /* VariableDeclaration */:
                    return checkVariableDeclaration(node);
                case 169 /* BindingElement */:
                    return checkBindingElement(node);
                case 221 /* ClassDeclaration */:
                    return checkClassDeclaration(node);
                case 222 /* InterfaceDeclaration */:
                    return checkInterfaceDeclaration(node);
                case 223 /* TypeAliasDeclaration */:
                    return checkTypeAliasDeclaration(node);
                case 224 /* EnumDeclaration */:
                    return checkEnumDeclaration(node);
                case 225 /* ModuleDeclaration */:
                    return checkModuleDeclaration(node);
                case 230 /* ImportDeclaration */:
                    return checkImportDeclaration(node);
                case 229 /* ImportEqualsDeclaration */:
                    return checkImportEqualsDeclaration(node);
                case 236 /* ExportDeclaration */:
                    return checkExportDeclaration(node);
                case 235 /* ExportAssignment */:
                    return checkExportAssignment(node);
                case 201 /* EmptyStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 217 /* DebuggerStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 239 /* 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 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                        checkFunctionExpressionOrObjectLiteralMethodDeferred(node);
                        break;
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        checkAccessorDeferred(node);
                        break;
                    case 192 /* ClassExpression */:
                        checkClassExpressionDeferred(node);
                        break;
                }
            }
        }
        function checkSourceFile(node) {
            var start = new Date().getTime();
            checkSourceFileWorker(node);
            ts.checkTime += new Date().getTime() - start;
        }
        // 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);
                potentialThisCollisions.length = 0;
                deferredNodes = [];
                deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
                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);
                    potentialThisCollisions.length = 0;
                }
                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) {
                checkSourceFile(sourceFile);
                return diagnostics.getDiagnostics(sourceFile.fileName);
            }
            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 === 212 /* WithStatement */ && node.parent.statement === node) {
                        return true;
                    }
                    node = node.parent;
                }
            }
            return false;
        }
        function getSymbolsInScope(location, meaning) {
            var symbols = {};
            var memberFlags = 0;
            if (isInsideWithStatementBody(location)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return [];
            }
            populateSymbols();
            return symbolsToArray(symbols);
            function populateSymbols() {
                while (location) {
                    if (location.locals && !isGlobalSourceFile(location)) {
                        copySymbols(location.locals, meaning);
                    }
                    switch (location.kind) {
                        case 256 /* SourceFile */:
                            if (!ts.isExternalOrCommonJsModule(location)) {
                                break;
                            }
                        case 225 /* ModuleDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 8914931 /* ModuleMember */);
                            break;
                        case 224 /* EnumDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
                            break;
                        case 192 /* ClassExpression */:
                            var className = location.name;
                            if (className) {
                                copySymbol(location.symbol, meaning);
                            }
                        // fall 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 221 /* ClassDeclaration */:
                        case 222 /* 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 (!(memberFlags & 32 /* Static */)) {
                                copySymbols(getSymbolOfNode(location).members, meaning & 793056 /* Type */);
                            }
                            break;
                        case 179 /* FunctionExpression */:
                            var funcName = location.name;
                            if (funcName) {
                                copySymbol(location.symbol, meaning);
                            }
                            break;
                    }
                    if (ts.introducesArgumentsExoticObject(location)) {
                        copySymbol(argumentsSymbol, meaning);
                    }
                    memberFlags = location.flags;
                    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 (symbol.flags & meaning) {
                    var id = symbol.name;
                    // 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 (!ts.hasProperty(symbols, id)) {
                        symbols[id] = symbol;
                    }
                }
            }
            function copySymbols(source, meaning) {
                if (meaning) {
                    for (var id in source) {
                        var symbol = source[id];
                        copySymbol(symbol, meaning);
                    }
                }
            }
        }
        function isTypeDeclarationName(name) {
            return name.kind === 69 /* Identifier */ &&
                isTypeDeclaration(name.parent) &&
                name.parent.name === name;
        }
        function isTypeDeclaration(node) {
            switch (node.kind) {
                case 141 /* TypeParameter */:
                case 221 /* ClassDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 223 /* TypeAliasDeclaration */:
                case 224 /* 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 === 139 /* QualifiedName */) {
                node = node.parent;
            }
            return node.parent && (node.parent.kind === 155 /* TypeReference */ || node.parent.kind === 267 /* JSDocTypeReference */);
        }
        function isHeritageClauseElementIdentifier(entityName) {
            var node = entityName;
            while (node.parent && node.parent.kind === 172 /* PropertyAccessExpression */) {
                node = node.parent;
            }
            return node.parent && node.parent.kind === 194 /* 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 === 139 /* QualifiedName */) {
                nodeOnRightSide = nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 229 /* ImportEqualsDeclaration */) {
                return nodeOnRightSide.parent.moduleReference === nodeOnRightSide && nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 235 /* ExportAssignment */) {
                return nodeOnRightSide.parent.expression === nodeOnRightSide && nodeOnRightSide.parent;
            }
            return undefined;
        }
        function isInRightSideOfImportOrExportAssignment(node) {
            return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
        }
        function getSymbolOfEntityNameOrPropertyAccessExpression(entityName) {
            if (ts.isDeclarationName(entityName)) {
                return getSymbolOfNode(entityName.parent);
            }
            if (ts.isInJavaScriptFile(entityName) && entityName.parent.kind === 172 /* PropertyAccessExpression */) {
                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 */:
                        return getSymbolOfNode(entityName.parent.parent);
                    default:
                }
            }
            if (entityName.parent.kind === 235 /* ExportAssignment */) {
                return resolveEntityName(entityName, 
                /*all meanings*/ 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */ | 8388608 /* Alias */);
            }
            if (entityName.kind !== 172 /* PropertyAccessExpression */) {
                if (isInRightSideOfImportOrExportAssignment(entityName)) {
                    // Since we already checked for ExportAssignment, this really could only be an Import
                    var importEqualsDeclaration = ts.getAncestor(entityName, 229 /* ImportEqualsDeclaration */);
                    ts.Debug.assert(importEqualsDeclaration !== undefined);
                    return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*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 === 194 /* ExpressionWithTypeArguments */) {
                    meaning = 793056 /* Type */;
                    // In a class 'extends' clause we are also looking for a value.
                    if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) {
                        meaning |= 107455 /* Value */;
                    }
                }
                else {
                    meaning = 1536 /* Namespace */;
                }
                meaning |= 8388608 /* Alias */;
                return resolveEntityName(entityName, meaning);
            }
            else if (ts.isExpression(entityName)) {
                if (ts.nodeIsMissing(entityName)) {
                    // Missing entity name.
                    return undefined;
                }
                if (entityName.kind === 69 /* Identifier */) {
                    if (ts.isJSXTagName(entityName) && isJsxIntrinsicIdentifier(entityName)) {
                        return getIntrinsicTagSymbol(entityName.parent);
                    }
                    return resolveEntityName(entityName, 107455 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
                }
                else if (entityName.kind === 172 /* PropertyAccessExpression */) {
                    var symbol = getNodeLinks(entityName).resolvedSymbol;
                    if (!symbol) {
                        checkPropertyAccessExpression(entityName);
                    }
                    return getNodeLinks(entityName).resolvedSymbol;
                }
                else if (entityName.kind === 139 /* QualifiedName */) {
                    var symbol = getNodeLinks(entityName).resolvedSymbol;
                    if (!symbol) {
                        checkQualifiedName(entityName);
                    }
                    return getNodeLinks(entityName).resolvedSymbol;
                }
            }
            else if (isTypeReferenceIdentifier(entityName)) {
                var meaning = (entityName.parent.kind === 155 /* TypeReference */ || entityName.parent.kind === 267 /* JSDocTypeReference */) ? 793056 /* Type */ : 1536 /* Namespace */;
                return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
            }
            else if (entityName.parent.kind === 246 /* JsxAttribute */) {
                return getJsxAttributePropertySymbol(entityName.parent);
            }
            if (entityName.parent.kind === 154 /* TypePredicate */) {
                return resolveEntityName(entityName, /*meaning*/ 1 /* FunctionScopedVariable */);
            }
            // Do we want to return undefined here?
            return undefined;
        }
        function getSymbolAtLocation(node) {
            if (node.kind === 256 /* 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 (ts.isDeclarationName(node)) {
                // This is a declaration, call getSymbolOfNode
                return getSymbolOfNode(node.parent);
            }
            else if (ts.isLiteralComputedPropertyDeclarationName(node)) {
                return getSymbolOfNode(node.parent.parent);
            }
            if (node.kind === 69 /* Identifier */) {
                if (isInRightSideOfImportOrExportAssignment(node)) {
                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
                }
                else if (node.parent.kind === 169 /* BindingElement */ &&
                    node.parent.parent.kind === 167 /* ObjectBindingPattern */ &&
                    node === node.parent.propertyName) {
                    var typeOfPattern = getTypeOfNode(node.parent.parent);
                    var propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, node.text);
                    if (propertyDeclaration) {
                        return propertyDeclaration;
                    }
                }
            }
            switch (node.kind) {
                case 69 /* Identifier */:
                case 172 /* PropertyAccessExpression */:
                case 139 /* QualifiedName */:
                    return getSymbolOfEntityNameOrPropertyAccessExpression(node);
                case 97 /* ThisKeyword */:
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    if (ts.isFunctionLike(container)) {
                        var sig = getSignatureFromDeclaration(container);
                        if (sig.thisParameter) {
                            return sig.thisParameter;
                        }
                    }
                // fallthrough
                case 95 /* SuperKeyword */:
                    var type = ts.isExpression(node) ? checkExpression(node) : getTypeFromTypeNode(node);
                    return type.symbol;
                case 165 /* ThisType */:
                    return getTypeFromTypeNode(node).symbol;
                case 121 /* ConstructorKeyword */:
                    // constructor keyword for an overload, should take us to the definition if it exist
                    var constructorDeclaration = node.parent;
                    if (constructorDeclaration && constructorDeclaration.kind === 148 /* Constructor */) {
                        return constructorDeclaration.parent.symbol;
                    }
                    return undefined;
                case 9 /* StringLiteral */:
                    // External module name in an import declaration
                    if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
                        ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
                        ((node.parent.kind === 230 /* ImportDeclaration */ || node.parent.kind === 236 /* ExportDeclaration */) &&
                            node.parent.moduleSpecifier === node)) {
                        return resolveExternalModuleName(node, node);
                    }
                // Fall through
                case 8 /* NumericLiteral */:
                    // index access
                    if (node.parent.kind === 173 /* ElementAccessExpression */ && node.parent.argumentExpression === node) {
                        var objectType = checkExpression(node.parent.expression);
                        if (objectType === unknownType)
                            return undefined;
                        var apparentType = getApparentType(objectType);
                        if (apparentType === unknownType)
                            return undefined;
                        return getPropertyOfType(apparentType, node.text);
                    }
                    break;
            }
            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 === 254 /* ShorthandPropertyAssignment */) {
                return resolveEntityName(location.name, 107455 /* Value */ | 8388608 /* 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 */ | 793056 /* Type */ | 1536 /* Namespace */ | 8388608 /* 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.isTypeNode(node)) {
                return getTypeFromTypeNode(node);
            }
            if (ts.isExpression(node)) {
                return getTypeOfExpression(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.
                return getBaseTypes(getDeclaredTypeOfSymbol(getSymbolOfNode(node.parent.parent)))[0];
            }
            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 (ts.isDeclarationName(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 === 171 /* ObjectLiteralExpression */ || expr.kind === 170 /* ArrayLiteralExpression */);
            // If this is from "for of"
            //     for ( { a } of elems) {
            //     }
            if (expr.parent.kind === 208 /* ForOfStatement */) {
                var iteratedType = checkRightHandSideOfForOf(expr.parent.expression);
                return checkDestructuringAssignment(expr, iteratedType || unknownType);
            }
            // If this is from "for" initializer
            //     for ({a } = elems[0];.....) { }
            if (expr.parent.kind === 187 /* BinaryExpression */) {
                var iteratedType = checkExpression(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 === 253 /* 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 === 170 /* ArrayLiteralExpression */);
            //    [{ property1: p1, property2 }] = elems;
            var typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent);
            var elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ 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.text);
        }
        function getTypeOfExpression(expr) {
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                expr = expr.parent;
            }
            return checkExpression(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 node.flags & 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 = createSymbolTable(getPropertiesOfType(type));
            if (getSignaturesOfType(type, 0 /* Call */).length || getSignaturesOfType(type, 1 /* Construct */).length) {
                ts.forEach(getPropertiesOfType(globalFunctionType), function (p) {
                    if (!ts.hasProperty(propsByName, p.name)) {
                        propsByName[p.name] = p;
                    }
                });
            }
            return getNamedMembers(propsByName);
        }
        function getRootSymbols(symbol) {
            if (symbol.flags & 268435456 /* SyntheticProperty */) {
                var symbols_3 = [];
                var name_20 = symbol.name;
                ts.forEach(getSymbolLinks(symbol).containingType.types, function (t) {
                    var symbol = getPropertyOfType(t, name_20);
                    if (symbol) {
                        symbols_3.push(symbol);
                    }
                });
                return symbols_3;
            }
            else if (symbol.flags & 67108864 /* Transient */) {
                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) {
            return getReferencedValueSymbol(node) === argumentsSymbol;
        }
        function moduleExportsSomeValue(moduleReferenceExpression) {
            var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
            if (!moduleSymbol) {
                // module not found - be conservative
                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.forEachValue(getExportsOfModule(moduleSymbol), isValue);
            }
            return symbolLinks.exportsSomeValue;
            function isValue(s) {
                s = resolveSymbol(s);
                return s && !!(s.flags & 107455 /* Value */);
            }
        }
        // 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) {
            var symbol = getReferencedValueSymbol(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 (exportSymbol.flags & 944 /* ExportHasLocal */) {
                        return undefined;
                    }
                    symbol = exportSymbol;
                }
                var parentSymbol = getParentOfSymbol(symbol);
                if (parentSymbol) {
                    if (parentSymbol.flags & 512 /* ValueModule */ && parentSymbol.valueDeclaration.kind === 256 /* SourceFile */) {
                        // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
                        if (parentSymbol.valueDeclaration === ts.getSourceFileOfNode(node)) {
                            return parentSymbol.valueDeclaration;
                        }
                    }
                    for (var n = node.parent; n; n = n.parent) {
                        if ((n.kind === 225 /* ModuleDeclaration */ || n.kind === 224 /* EnumDeclaration */) && getSymbolOfNode(n) === parentSymbol) {
                            return n;
                        }
                    }
                }
            }
        }
        // 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) {
            var symbol = getReferencedValueSymbol(node);
            return symbol && symbol.flags & 8388608 /* Alias */ ? getDeclarationOfAliasSymbol(symbol) : 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.name, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) {
                            // 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 === 199 /* 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) {
            var symbol = getReferencedValueSymbol(node);
            return symbol && isSymbolOfDeclarationWithCollidingName(symbol) ? symbol.valueDeclaration : 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) {
            return isSymbolOfDeclarationWithCollidingName(getSymbolOfNode(node));
        }
        function isValueAliasDeclaration(node) {
            switch (node.kind) {
                case 229 /* ImportEqualsDeclaration */:
                case 231 /* ImportClause */:
                case 232 /* NamespaceImport */:
                case 234 /* ImportSpecifier */:
                case 238 /* ExportSpecifier */:
                    return isAliasResolvedToValue(getSymbolOfNode(node));
                case 236 /* ExportDeclaration */:
                    var exportClause = node.exportClause;
                    return exportClause && ts.forEach(exportClause.elements, isValueAliasDeclaration);
                case 235 /* ExportAssignment */:
                    return node.expression && node.expression.kind === 69 /* Identifier */ ? isAliasResolvedToValue(getSymbolOfNode(node)) : true;
            }
            return false;
        }
        function isTopLevelValueImportEqualsWithEntityName(node) {
            if (node.parent.kind !== 256 /* 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 (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 getNodeCheckFlags(node) {
            return getNodeLinks(node).flags;
        }
        function getEnumMemberValue(node) {
            computeEnumMemberValues(node.parent);
            return getNodeLinks(node).enumMemberValue;
        }
        function getConstantValue(node) {
            if (node.kind === 255 /* 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 & 80896 /* ObjectType */ && getSignaturesOfType(type, 0 /* Call */).length > 0;
        }
        function getTypeReferenceSerializationKind(typeName) {
            // 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);
            var constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined;
            if (constructorType && isConstructorType(constructorType)) {
                return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
            }
            // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
            var typeSymbol = resolveEntityName(typeName, 793056 /* Type */, /*ignoreErrors*/ true);
            // 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 (isTypeOfKind(type, 16 /* Void */)) {
                return ts.TypeReferenceSerializationKind.VoidType;
            }
            else if (isTypeOfKind(type, 8 /* Boolean */)) {
                return ts.TypeReferenceSerializationKind.BooleanType;
            }
            else if (isTypeOfKind(type, 132 /* NumberLike */)) {
                return ts.TypeReferenceSerializationKind.NumberLikeType;
            }
            else if (isTypeOfKind(type, 258 /* StringLike */)) {
                return ts.TypeReferenceSerializationKind.StringLikeType;
            }
            else if (isTypeOfKind(type, 8192 /* Tuple */)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else if (isTypeOfKind(type, 16777216 /* 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 */))
                ? getTypeOfSymbol(symbol)
                : unknownType;
            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(getTypeOfExpression(expr));
            getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
        }
        function writeBaseConstructorTypeOfClass(node, enclosingDeclaration, flags, writer) {
            var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(node));
            resolveBaseTypesOfClass(classType);
            var baseType = classType.resolvedBaseTypes.length ? classType.resolvedBaseTypes[0] : unknownType;
            getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags);
        }
        function hasGlobalName(name) {
            return ts.hasProperty(globals, name);
        }
        function getReferencedValueSymbol(reference) {
            return getNodeLinks(reference).resolvedSymbol ||
                resolveName(reference, reference.text, 107455 /* Value */ | 1048576 /* ExportValue */ | 8388608 /* Alias */, 
                /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined);
        }
        function getReferencedValueDeclaration(reference) {
            ts.Debug.assert(!ts.nodeIsSynthesized(reference));
            var symbol = getReferencedValueSymbol(reference);
            return symbol && getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
        }
        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.createFileMap();
                for (var key in resolvedTypeReferenceDirectives) {
                    if (!ts.hasProperty(resolvedTypeReferenceDirectives, key)) {
                        continue;
                    }
                    var resolvedDirective = resolvedTypeReferenceDirectives[key];
                    if (!resolvedDirective) {
                        continue;
                    }
                    var file = host.getSourceFile(resolvedDirective.resolvedFileName);
                    fileToDirective.set(file.path, key);
                }
            }
            return {
                getReferencedExportContainer: getReferencedExportContainer,
                getReferencedImportDeclaration: getReferencedImportDeclaration,
                getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName,
                isDeclarationWithCollidingName: isDeclarationWithCollidingName,
                isValueAliasDeclaration: isValueAliasDeclaration,
                hasGlobalName: hasGlobalName,
                isReferencedAliasDeclaration: isReferencedAliasDeclaration,
                getNodeCheckFlags: getNodeCheckFlags,
                isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName,
                isDeclarationVisible: isDeclarationVisible,
                isImplementationOfOverload: isImplementationOfOverload,
                writeTypeOfDeclaration: writeTypeOfDeclaration,
                writeReturnTypeOfSignatureDeclaration: writeReturnTypeOfSignatureDeclaration,
                writeTypeOfExpression: writeTypeOfExpression,
                writeBaseConstructorTypeOfClass: writeBaseConstructorTypeOfClass,
                isSymbolAccessible: isSymbolAccessible,
                isEntityNameVisible: isEntityNameVisible,
                getConstantValue: getConstantValue,
                collectLinkedAliases: collectLinkedAliases,
                getReferencedValueDeclaration: getReferencedValueDeclaration,
                getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
                isOptionalParameter: isOptionalParameter,
                moduleExportsSomeValue: moduleExportsSomeValue,
                isArgumentsLocalBinding: isArgumentsLocalBinding,
                getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration,
                getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName,
                getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol
            };
            // 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 === 172 /* PropertyAccessExpression */) || (node.kind === 69 /* Identifier */ && isInTypeQuery(node))
                    ? 107455 /* Value */ | 1048576 /* ExportValue */
                    : 793056 /* Type */ | 1536 /* 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);
                        }
                    }
                }
                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_12 = getParentOfSymbol(current);
                    if (parent_12) {
                        current = parent_12;
                    }
                    else {
                        break;
                    }
                }
                if (current.valueDeclaration && current.valueDeclaration.kind === 256 /* 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.contains(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, 256 /* SourceFile */);
        }
        function initializeTypeChecker() {
            // Bind all source files and propagate errors
            ts.forEach(host.getSourceFiles(), function (file) {
                ts.bindSourceFile(file, compilerOptions);
            });
            var augmentations;
            // Initialize global symbol table
            ts.forEach(host.getSourceFiles(), function (file) {
                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) {
                    mergeSymbolTable(globals, file.symbol.globalExports);
                }
            });
            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 _i = 0, augmentations_1 = augmentations; _i < augmentations_1.length; _i++) {
                    var list = augmentations_1[_i];
                    for (var _a = 0, list_2 = list; _a < list_2.length; _a++) {
                        var augmentation = list_2[_a];
                        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");
            getSymbolLinks(unknownSymbol).type = unknownType;
            // Initialize special types
            globalArrayType = getGlobalType("Array", /*arity*/ 1);
            globalObjectType = getGlobalType("Object");
            globalFunctionType = getGlobalType("Function");
            globalStringType = getGlobalType("String");
            globalNumberType = getGlobalType("Number");
            globalBooleanType = getGlobalType("Boolean");
            globalRegExpType = getGlobalType("RegExp");
            jsxElementType = getExportedTypeFromNamespace("JSX", JsxNames.Element);
            getGlobalClassDecoratorType = ts.memoize(function () { return getGlobalType("ClassDecorator"); });
            getGlobalPropertyDecoratorType = ts.memoize(function () { return getGlobalType("PropertyDecorator"); });
            getGlobalMethodDecoratorType = ts.memoize(function () { return getGlobalType("MethodDecorator"); });
            getGlobalParameterDecoratorType = ts.memoize(function () { return getGlobalType("ParameterDecorator"); });
            getGlobalTypedPropertyDescriptorType = ts.memoize(function () { return getGlobalType("TypedPropertyDescriptor", /*arity*/ 1); });
            getGlobalESSymbolConstructorSymbol = ts.memoize(function () { return getGlobalValueSymbol("Symbol"); });
            getGlobalPromiseType = ts.memoize(function () { return getGlobalType("Promise", /*arity*/ 1); });
            tryGetGlobalPromiseType = ts.memoize(function () { return getGlobalSymbol("Promise", 793056 /* Type */, /*diagnostic*/ undefined) && getGlobalPromiseType(); });
            getGlobalPromiseLikeType = ts.memoize(function () { return getGlobalType("PromiseLike", /*arity*/ 1); });
            getInstantiatedGlobalPromiseLikeType = ts.memoize(createInstantiatedPromiseLikeType);
            getGlobalPromiseConstructorSymbol = ts.memoize(function () { return getGlobalValueSymbol("Promise"); });
            getGlobalPromiseConstructorLikeType = ts.memoize(function () { return getGlobalType("PromiseConstructorLike"); });
            getGlobalThenableType = ts.memoize(createThenableType);
            getGlobalTemplateStringsArrayType = ts.memoize(function () { return getGlobalType("TemplateStringsArray"); });
            if (languageVersion >= 2 /* ES6 */) {
                getGlobalESSymbolType = ts.memoize(function () { return getGlobalType("Symbol"); });
                getGlobalIterableType = ts.memoize(function () { return getGlobalType("Iterable", /*arity*/ 1); });
                getGlobalIteratorType = ts.memoize(function () { return getGlobalType("Iterator", /*arity*/ 1); });
                getGlobalIterableIteratorType = ts.memoize(function () { return getGlobalType("IterableIterator", /*arity*/ 1); });
            }
            else {
                getGlobalESSymbolType = ts.memoize(function () { return emptyObjectType; });
                getGlobalIterableType = ts.memoize(function () { return emptyGenericType; });
                getGlobalIteratorType = ts.memoize(function () { return emptyGenericType; });
                getGlobalIterableIteratorType = ts.memoize(function () { return emptyGenericType; });
            }
            anyArrayType = createArrayType(anyType);
            var symbol = getGlobalSymbol("ReadonlyArray", 793056 /* Type */, /*diagnostic*/ undefined);
            globalReadonlyArrayType = symbol && getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
            anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
        }
        function createInstantiatedPromiseLikeType() {
            var promiseLikeType = getGlobalPromiseLikeType();
            if (promiseLikeType !== emptyGenericType) {
                return createTypeReference(promiseLikeType, [anyType]);
            }
            return emptyObjectType;
        }
        function createThenableType() {
            // build the thenable type that is used to verify against a non-promise "thenable" operand to `await`.
            var thenPropertySymbol = createSymbol(67108864 /* Transient */ | 4 /* Property */, "then");
            getSymbolLinks(thenPropertySymbol).type = globalFunctionType;
            var thenableType = createObjectType(65536 /* Anonymous */);
            thenableType.properties = [thenPropertySymbol];
            thenableType.members = createSymbolTable(thenableType.properties);
            thenableType.callSignatures = [];
            thenableType.constructSignatures = [];
            return thenableType;
        }
        // GRAMMAR CHECKING
        function checkGrammarDecorators(node) {
            if (!node.decorators) {
                return false;
            }
            if (!ts.nodeCanBeDecorated(node)) {
                if (node.kind === 147 /* 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 === 149 /* GetAccessor */ || node.kind === 150 /* 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) {
            switch (node.kind) {
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 148 /* Constructor */:
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 153 /* IndexSignature */:
                case 225 /* ModuleDeclaration */:
                case 230 /* ImportDeclaration */:
                case 229 /* ImportEqualsDeclaration */:
                case 236 /* ExportDeclaration */:
                case 235 /* ExportAssignment */:
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                case 142 /* Parameter */:
                    break;
                case 220 /* FunctionDeclaration */:
                    if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== 118 /* AsyncKeyword */) &&
                        node.parent.kind !== 226 /* ModuleBlock */ && node.parent.kind !== 256 /* SourceFile */) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                    break;
                case 221 /* ClassDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 200 /* VariableStatement */:
                case 223 /* TypeAliasDeclaration */:
                    if (node.modifiers && node.parent.kind !== 226 /* ModuleBlock */ && node.parent.kind !== 256 /* SourceFile */) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                    break;
                case 224 /* EnumDeclaration */:
                    if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== 74 /* ConstKeyword */) &&
                        node.parent.kind !== 226 /* ModuleBlock */ && node.parent.kind !== 256 /* SourceFile */) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                    break;
                default:
                    return false;
            }
            if (!node.modifiers) {
                return;
            }
            var lastStatic, lastPrivate, lastProtected, lastDeclare, lastAsync, lastReadonly;
            var flags = 0;
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                if (modifier.kind !== 128 /* ReadonlyKeyword */) {
                    if (node.kind === 144 /* PropertySignature */ || node.kind === 146 /* MethodSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind));
                    }
                    if (node.kind === 153 /* IndexSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind));
                    }
                }
                switch (modifier.kind) {
                    case 74 /* ConstKeyword */:
                        if (node.kind !== 224 /* EnumDeclaration */ && node.parent.kind === 221 /* ClassDeclaration */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(74 /* ConstKeyword */));
                        }
                        break;
                    case 112 /* PublicKeyword */:
                    case 111 /* ProtectedKeyword */:
                    case 110 /* PrivateKeyword */:
                        var text = visibilityToString(ts.modifierToFlag(modifier.kind));
                        if (modifier.kind === 111 /* ProtectedKeyword */) {
                            lastProtected = modifier;
                        }
                        else if (modifier.kind === 110 /* PrivateKeyword */) {
                            lastPrivate = modifier;
                        }
                        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 === 226 /* ModuleBlock */ || node.parent.kind === 256 /* 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 === 110 /* 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 113 /* 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 === 226 /* ModuleBlock */ || node.parent.kind === 256 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
                        }
                        else if (node.kind === 142 /* 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 128 /* ReadonlyKeyword */:
                        if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly");
                        }
                        else if (node.kind !== 145 /* PropertyDeclaration */ && node.kind !== 144 /* PropertySignature */ && node.kind !== 153 /* IndexSignature */ && node.kind !== 142 /* 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 82 /* 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 === 221 /* ClassDeclaration */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
                        }
                        else if (node.kind === 142 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
                        }
                        flags |= 1 /* Export */;
                        break;
                    case 122 /* 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 === 221 /* ClassDeclaration */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
                        }
                        else if (node.kind === 142 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
                        }
                        else if (ts.isInAmbientContext(node.parent) && node.parent.kind === 226 /* ModuleBlock */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
                        }
                        flags |= 2 /* Ambient */;
                        lastDeclare = modifier;
                        break;
                    case 115 /* AbstractKeyword */:
                        if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract");
                        }
                        if (node.kind !== 221 /* ClassDeclaration */) {
                            if (node.kind !== 147 /* MethodDeclaration */ &&
                                node.kind !== 145 /* PropertyDeclaration */ &&
                                node.kind !== 149 /* GetAccessor */ &&
                                node.kind !== 150 /* SetAccessor */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
                            }
                            if (!(node.parent.kind === 221 /* ClassDeclaration */ && node.parent.flags & 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 118 /* 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 === 142 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
                        }
                        flags |= 256 /* Async */;
                        lastAsync = modifier;
                        break;
                }
            }
            if (node.kind === 148 /* 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 === 230 /* ImportDeclaration */ || node.kind === 229 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) {
                return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
            }
            else if (node.kind === 142 /* 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 === 142 /* 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);
            }
        }
        function checkGrammarAsyncModifier(node, asyncModifier) {
            if (languageVersion < 2 /* ES6 */) {
                return grammarErrorOnNode(asyncModifier, ts.Diagnostics.Async_functions_are_only_available_when_targeting_ECMAScript_2015_or_higher);
            }
            switch (node.kind) {
                case 147 /* MethodDeclaration */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    if (!node.asteriskToken) {
                        return false;
                    }
                    break;
            }
            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;
                var sourceFile = ts.getSourceFileOfNode(list[0]);
                return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Trailing_comma_not_allowed);
            }
        }
        function checkGrammarTypeParameterList(node, 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, node.typeParameters, file) ||
                checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
        }
        function checkGrammarArrowFunction(node, file) {
            if (node.kind === 180 /* 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 (parameter.flags & 1023 /* Modifier */) {
                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 !== 132 /* StringKeyword */ && parameter.type.kind !== 130 /* 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(node, args) {
            if (args) {
                var sourceFile = ts.getSourceFileOfNode(node);
                for (var _i = 0, args_1 = args; _i < args_1.length; _i++) {
                    var arg = args_1[_i];
                    if (arg.kind === 193 /* OmittedExpression */) {
                        return grammarErrorAtPos(sourceFile, arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
                    }
                }
            }
        }
        function checkGrammarArguments(node, args) {
            return checkGrammarForOmittedArgument(node, args);
        }
        function checkGrammarHeritageClause(node) {
            var types = node.types;
            if (checkGrammarForDisallowedTrailingComma(types)) {
                return true;
            }
            if (types && types.length === 0) {
                var listType = ts.tokenToString(node.token);
                var sourceFile = ts.getSourceFileOfNode(node);
                return grammarErrorAtPos(sourceFile, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
            }
        }
        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 === 83 /* 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 === 106 /* 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 === 83 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 106 /* 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 !== 140 /* ComputedPropertyName */) {
                return false;
            }
            var computedPropertyName = node;
            if (computedPropertyName.expression.kind === 187 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 24 /* 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 === 220 /* FunctionDeclaration */ ||
                    node.kind === 179 /* FunctionExpression */ ||
                    node.kind === 147 /* 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);
                }
                if (languageVersion < 2 /* ES6 */) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher);
                }
            }
        }
        function checkGrammarForInvalidQuestionMark(node, questionToken, message) {
            if (questionToken) {
                return grammarErrorOnNode(questionToken, message);
            }
        }
        function checkGrammarObjectLiteralExpression(node, inDestructuring) {
            var seen = {};
            var Property = 1;
            var GetAccessor = 2;
            var SetAccessor = 4;
            var GetOrSetAccessor = GetAccessor | SetAccessor;
            var _loop_2 = function(prop) {
                var name_21 = prop.name;
                if (prop.kind === 193 /* OmittedExpression */ ||
                    name_21.kind === 140 /* ComputedPropertyName */) {
                    // If the name is not a ComputedPropertyName, the grammar checking will skip it
                    checkGrammarComputedPropertyName(name_21);
                }
                if (prop.kind === 254 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
                    // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
                    // outside of destructuring it is a syntax error
                    return { value: 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
                ts.forEach(prop.modifiers, function (mod) {
                    if (mod.kind !== 118 /* AsyncKeyword */ || prop.kind !== 147 /* 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 === 253 /* PropertyAssignment */ || prop.kind === 254 /* ShorthandPropertyAssignment */) {
                    // Grammar checking for computedPropertyName and shorthandPropertyAssignment
                    checkGrammarForInvalidQuestionMark(prop, prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                    if (name_21.kind === 8 /* NumericLiteral */) {
                        checkGrammarNumericLiteral(name_21);
                    }
                    currentKind = Property;
                }
                else if (prop.kind === 147 /* MethodDeclaration */) {
                    currentKind = Property;
                }
                else if (prop.kind === 149 /* GetAccessor */) {
                    currentKind = GetAccessor;
                }
                else if (prop.kind === 150 /* SetAccessor */) {
                    currentKind = SetAccessor;
                }
                else {
                    ts.Debug.fail("Unexpected syntax kind:" + prop.kind);
                }
                var effectiveName = ts.getPropertyNameForPropertyNameNode(name_21);
                if (effectiveName === undefined) {
                    return "continue";
                }
                if (!ts.hasProperty(seen, effectiveName)) {
                    seen[effectiveName] = currentKind;
                }
                else {
                    var existingKind = seen[effectiveName];
                    if (currentKind === Property && existingKind === Property) {
                        grammarErrorOnNode(name_21, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name_21));
                    }
                    else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
                        if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
                            seen[effectiveName] = currentKind | existingKind;
                        }
                        else {
                            return { value: grammarErrorOnNode(name_21, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name) };
                        }
                    }
                    else {
                        return { value: grammarErrorOnNode(name_21, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name) };
                    }
                }
            };
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var prop = _a[_i];
                var state_3 = _loop_2(prop);
                if (typeof state_3 === "object") return state_3.value;
            }
        }
        function checkGrammarJsxElement(node) {
            var seen = {};
            for (var _i = 0, _a = node.attributes; _i < _a.length; _i++) {
                var attr = _a[_i];
                if (attr.kind === 247 /* JsxSpreadAttribute */) {
                    continue;
                }
                var jsxAttr = attr;
                var name_22 = jsxAttr.name;
                if (!ts.hasProperty(seen, name_22.text)) {
                    seen[name_22.text] = true;
                }
                else {
                    return grammarErrorOnNode(name_22, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
                }
                var initializer = jsxAttr.initializer;
                if (initializer && initializer.kind === 248 /* 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.initializer.kind === 219 /* 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 === 207 /* 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 === 207 /* 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 === 207 /* 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 && !(accessor.flags & 128 /* Abstract */)) {
                return grammarErrorAtPos(ts.getSourceFileOfNode(accessor), accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
            }
            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 === 149 /* GetAccessor */ ?
                    ts.Diagnostics.A_get_accessor_cannot_have_parameters :
                    ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
            }
            else if (kind === 150 /* 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 === 149 /* GetAccessor */ ? 0 : 1);
        }
        function getAccessorThisParameter(accessor) {
            if (accessor.parameters.length === (accessor.kind === 149 /* GetAccessor */ ? 1 : 2) &&
                accessor.parameters[0].name.kind === 69 /* Identifier */ &&
                accessor.parameters[0].name.originalKeywordKind === 97 /* ThisKeyword */) {
                return accessor.parameters[0];
            }
        }
        function getFunctionLikeThisParameter(func) {
            if (func.parameters.length &&
                func.parameters[0].name.kind === 69 /* Identifier */ &&
                func.parameters[0].name.originalKeywordKind === 97 /* ThisKeyword */) {
                return func.parameters[0];
            }
        }
        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 === 171 /* ObjectLiteralExpression */) {
                if (checkGrammarForInvalidQuestionMark(node, node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) {
                    return true;
                }
                else if (node.body === undefined) {
                    return grammarErrorAtPos(ts.getSourceFileOfNode(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 === 222 /* 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 === 159 /* 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 214 /* LabeledStatement */:
                        if (node.label && current.label.text === node.label.text) {
                            // found matching label - verify that label usage is correct
                            // continue can only target labels that are on iteration statements
                            var isMisplacedContinueLabel = node.kind === 209 /* 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 213 /* SwitchStatement */:
                        if (node.kind === 210 /* 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 === 210 /* 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 === 210 /* 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_an_array_destructuring_pattern);
                }
                if (node.name.kind === 168 /* ArrayBindingPattern */ || node.name.kind === 167 /* ObjectBindingPattern */) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
                }
                if (node.initializer) {
                    // Error on equals token which immediate precedes the initializer
                    return grammarErrorAtPos(ts.getSourceFileOfNode(node), node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                }
            }
        }
        function checkGrammarVariableDeclaration(node) {
            if (node.parent.parent.kind !== 207 /* ForInStatement */ && node.parent.parent.kind !== 208 /* ForOfStatement */) {
                if (ts.isInAmbientContext(node)) {
                    if (node.initializer) {
                        // Error on equals token which immediate precedes the initializer
                        var equalsTokenLength = "=".length;
                        return grammarErrorAtPos(ts.getSourceFileOfNode(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);
                    }
                }
            }
            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 checkGrammarNameInLetOrConstDeclarations(name) {
            if (name.kind === 69 /* Identifier */) {
                if (name.originalKeywordKind === 108 /* 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 (element.kind !== 193 /* OmittedExpression */) {
                        checkGrammarNameInLetOrConstDeclarations(element.name);
                    }
                }
            }
        }
        function checkGrammarVariableDeclarationList(declarationList) {
            var declarations = declarationList.declarations;
            if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
                return true;
            }
            if (!declarationList.declarations.length) {
                return grammarErrorAtPos(ts.getSourceFileOfNode(declarationList), declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
            }
        }
        function allowLetAndConstDeclarations(parent) {
            switch (parent.kind) {
                case 203 /* IfStatement */:
                case 204 /* DoStatement */:
                case 205 /* WhileStatement */:
                case 212 /* WithStatement */:
                case 206 /* ForStatement */:
                case 207 /* ForInStatement */:
                case 208 /* ForOfStatement */:
                    return false;
                case 214 /* 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 hasParseDiagnostics(sourceFile) {
            return sourceFile.parseDiagnostics.length > 0;
        }
        function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2));
                return true;
            }
        }
        function grammarErrorAtPos(sourceFile, start, length, message, arg0, arg1, arg2) {
            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(ts.getSourceFileOfNode(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 === 222 /* 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 === 159 /* 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,
            // 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 === 222 /* InterfaceDeclaration */ ||
                node.kind === 223 /* TypeAliasDeclaration */ ||
                node.kind === 230 /* ImportDeclaration */ ||
                node.kind === 229 /* ImportEqualsDeclaration */ ||
                node.kind === 236 /* ExportDeclaration */ ||
                node.kind === 235 /* ExportAssignment */ ||
                (node.flags & 2 /* Ambient */) ||
                (node.flags & (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 === 200 /* 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 (isAccessor(node.parent.kind)) {
                    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 === 199 /* Block */ || node.parent.kind === 226 /* ModuleBlock */ || node.parent.kind === 256 /* 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 {
                }
            }
        }
        function checkGrammarNumericLiteral(node) {
            // Grammar checking
            if (node.isOctalLiteral && languageVersion >= 1 /* ES5 */) {
                return grammarErrorOnNode(node, ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
            }
        }
        function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2));
                return true;
            }
        }
        var _a;
    }
    ts.createTypeChecker = createTypeChecker;
})(ts || (ts = {}));
/// <reference path="checker.ts"/>
/* @internal */
var ts;
(function (ts) {
    var nullSourceMapWriter;
    // Used for initialize lastEncodedSourceMapSpan and reset lastEncodedSourceMapSpan when updateLastEncodedAndRecordedSpans
    var defaultLastEncodedSourceMapSpan = {
        emittedLine: 1,
        emittedColumn: 1,
        sourceLine: 1,
        sourceColumn: 1,
        sourceIndex: 0
    };
    function getNullSourceMapWriter() {
        if (nullSourceMapWriter === undefined) {
            nullSourceMapWriter = {
                getSourceMapData: function () { return undefined; },
                setSourceFile: function (sourceFile) { },
                emitStart: function (range) { },
                emitEnd: function (range, stopOverridingSpan) { },
                emitPos: function (pos) { },
                changeEmitSourcePos: function () { },
                getText: function () { return undefined; },
                getSourceMappingURL: function () { return undefined; },
                initialize: function (filePath, sourceMapFilePath, sourceFiles, isBundledEmit) { },
                reset: function () { }
            };
        }
        return nullSourceMapWriter;
    }
    ts.getNullSourceMapWriter = getNullSourceMapWriter;
    function createSourceMapWriter(host, writer) {
        var compilerOptions = host.getCompilerOptions();
        var currentSourceFile;
        var sourceMapDir; // The directory in which sourcemap will be
        var stopOverridingSpan = false;
        var modifyLastSourcePos = false;
        // 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;
        return {
            getSourceMapData: function () { return sourceMapData; },
            setSourceFile: setSourceFile,
            emitPos: emitPos,
            emitStart: emitStart,
            emitEnd: emitEnd,
            changeEmitSourcePos: changeEmitSourcePos,
            getText: getText,
            getSourceMappingURL: getSourceMappingURL,
            initialize: initialize,
            reset: reset
        };
        function initialize(filePath, sourceMapFilePath, sourceFiles, isBundledEmit) {
            if (sourceMapData) {
                reset();
            }
            currentSourceFile = 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 (!isBundledEmit) {
                    ts.Debug.assert(sourceFiles.length === 1);
                    // 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(sourceFiles[0], 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));
            }
        }
        function reset() {
            currentSourceFile = undefined;
            sourceMapDir = undefined;
            sourceMapSourceIndex = undefined;
            lastRecordedSourceMapSpan = undefined;
            lastEncodedSourceMapSpan = undefined;
            lastEncodedNameIndex = undefined;
            sourceMapData = undefined;
        }
        function updateLastEncodedAndRecordedSpans() {
            if (modifyLastSourcePos) {
                // Reset the source pos
                modifyLastSourcePos = false;
                // Change Last recorded Map with last encoded emit line and character
                lastRecordedSourceMapSpan.emittedLine = lastEncodedSourceMapSpan.emittedLine;
                lastRecordedSourceMapSpan.emittedColumn = lastEncodedSourceMapSpan.emittedColumn;
                // Pop sourceMapDecodedMappings to remove last entry
                sourceMapData.sourceMapDecodedMappings.pop();
                // Point the lastEncodedSourceMapSpace to the previous encoded sourceMapSpan
                // If the list is empty which indicates that we are at the beginning of the file,
                // we have to reset it to default value (same value when we first initialize sourceMapWriter)
                lastEncodedSourceMapSpan = sourceMapData.sourceMapDecodedMappings.length ?
                    sourceMapData.sourceMapDecodedMappings[sourceMapData.sourceMapDecodedMappings.length - 1] :
                    defaultLastEncodedSourceMapSpan;
                // TODO: Update lastEncodedNameIndex
                // Since we dont support this any more, lets not worry about it right now.
                // When we start supporting nameIndex, we will get back to this
                // Change the encoded source map
                var sourceMapMappings = sourceMapData.sourceMapMappings;
                var lenthToSet = sourceMapMappings.length - 1;
                for (; lenthToSet >= 0; lenthToSet--) {
                    var currentChar = sourceMapMappings.charAt(lenthToSet);
                    if (currentChar === ",") {
                        // Separator for the entry found
                        break;
                    }
                    if (currentChar === ";" && lenthToSet !== 0 && sourceMapMappings.charAt(lenthToSet - 1) !== ";") {
                        // Last line separator found
                        break;
                    }
                }
                sourceMapData.sourceMapMappings = sourceMapMappings.substr(0, Math.max(0, lenthToSet));
            }
        }
        // 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);
        }
        function emitPos(pos) {
            if (pos === -1) {
                return;
            }
            var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSourceFile, pos);
            // Convert the location to be one-based.
            sourceLinePos.line++;
            sourceLinePos.character++;
            var emittedLine = writer.getLine();
            var emittedColumn = writer.getColumn();
            // If this location wasn't recorded or the location in source is going backwards, record the span
            if (!lastRecordedSourceMapSpan ||
                lastRecordedSourceMapSpan.emittedLine !== emittedLine ||
                lastRecordedSourceMapSpan.emittedColumn !== emittedColumn ||
                (lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
                    (lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
                        (lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
                // Encode the last recordedSpan before assigning new
                encodeLastRecordedSourceMapSpan();
                // New span
                lastRecordedSourceMapSpan = {
                    emittedLine: emittedLine,
                    emittedColumn: emittedColumn,
                    sourceLine: sourceLinePos.line,
                    sourceColumn: sourceLinePos.character,
                    sourceIndex: sourceMapSourceIndex
                };
                stopOverridingSpan = false;
            }
            else if (!stopOverridingSpan) {
                // 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;
            }
            updateLastEncodedAndRecordedSpans();
        }
        function getStartPos(range) {
            var rangeHasDecorators = !!range.decorators;
            return range.pos !== -1 ? ts.skipTrivia(currentSourceFile.text, rangeHasDecorators ? range.decorators.end : range.pos) : -1;
        }
        function emitStart(range) {
            emitPos(getStartPos(range));
        }
        function emitEnd(range, stopOverridingEnd) {
            emitPos(range.end);
            stopOverridingSpan = stopOverridingEnd;
        }
        function changeEmitSourcePos() {
            ts.Debug.assert(!modifyLastSourcePos);
            modifyLastSourcePos = true;
        }
        function setSourceFile(sourceFile) {
            currentSourceFile = sourceFile;
            // 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, currentSourceFile.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(sourceFile.fileName);
                if (compilerOptions.inlineSources) {
                    sourceMapData.sourceMapSourcesContent.push(sourceFile.text);
                }
            }
        }
        function getText() {
            encodeLastRecordedSourceMapSpan();
            return ts.stringify({
                version: 3,
                file: sourceMapData.sourceMapFile,
                sourceRoot: sourceMapData.sourceMapSourceRoot,
                sources: sourceMapData.sourceMapSources,
                names: sourceMapData.sourceMapNames,
                mappings: sourceMapData.sourceMapMappings,
                sourcesContent: sourceMapData.sourceMapSourcesContent
            });
        }
        function getSourceMappingURL() {
            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="checker.ts"/>
/* @internal */
var ts;
(function (ts) {
    function getDeclarationDiagnostics(host, resolver, targetSourceFile) {
        var declarationDiagnostics = ts.createDiagnosticCollection();
        ts.forEachExpectedEmitFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
        return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
        function getDeclarationDiagnosticsFromFile(_a, sources, isBundledEmit) {
            var declarationFilePath = _a.declarationFilePath;
            emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit);
        }
    }
    ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
    function emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit) {
        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 ? function (declaration) { } : writeJsDocComments;
        var emit = compilerOptions.stripInternal ? stripInternal : emitNode;
        var noDeclare;
        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)) {
                            addedGlobalFileReference = true;
                        }
                        emittedReferencedFiles.push(referencedFile);
                    }
                });
            }
            resultHasExternalModuleIndicator = false;
            if (!isBundledEmit || !ts.isExternalModule(sourceFile)) {
                noDeclare = false;
                emitSourceFile(sourceFile);
            }
            else if (ts.isExternalModule(sourceFile)) {
                noDeclare = true;
                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 === 230 /* 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) {
            for (var directive in usedTypeDirectiveReferences) {
                if (ts.hasProperty(usedTypeDirectiveReferences, 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 comment.indexOf("@internal") >= 0;
        }
        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.writeKeyword = writer.write;
            writer.writeOperator = writer.write;
            writer.writePunctuation = writer.write;
            writer.writeSpace = writer.write;
            writer.writeStringLiteral = writer.writeLiteral;
            writer.writeParameter = 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 === 218 /* VariableDeclaration */) {
                    nodeToCheck = declaration.parent.parent;
                }
                else if (declaration.kind === 233 /* NamedImports */ || declaration.kind === 234 /* ImportSpecifier */ || declaration.kind === 231 /* 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 === 230 /* 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 === 225 /* ModuleDeclaration */) {
                            ts.Debug.assert(asynchronousSubModuleDeclarationEmitInfo === undefined);
                            asynchronousSubModuleDeclarationEmitInfo = [];
                        }
                        writeModuleElement(nodeToCheck);
                        if (nodeToCheck.kind === 225 /* ModuleDeclaration */) {
                            moduleElementEmitInfo.subModuleElementDeclarationEmitInfo = asynchronousSubModuleDeclarationEmitInfo;
                            asynchronousSubModuleDeclarationEmitInfo = undefined;
                        }
                        moduleElementEmitInfo.asynchronousOutput = writer.getText();
                    }
                }
            });
            setWriter(oldWriter);
        }
        function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) {
            if (!typeReferenceDirectives) {
                return;
            }
            if (!usedTypeDirectiveReferences) {
                usedTypeDirectiveReferences = {};
            }
            for (var _i = 0, typeReferenceDirectives_1 = typeReferenceDirectives; _i < typeReferenceDirectives_1.length; _i++) {
                var directive = typeReferenceDirectives_1[_i];
                if (!ts.hasProperty(usedTypeDirectiveReferences, directive)) {
                    usedTypeDirectiveReferences[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));
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
        }
        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(": ");
            if (type) {
                // Write the type
                emitType(type);
            }
            else {
                errorNameNode = declaration.name;
                resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, 2 /* UseTypeOfFunction */, 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, 2 /* UseTypeOfFunction */, writer);
                errorNameNode = undefined;
            }
        }
        function emitLines(nodes) {
            for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                var node = nodes_2[_i];
                emit(node);
            }
        }
        function emitSeparatedList(nodes, separator, eachNodeEmitFn, canEmitFn) {
            var currentWriterPos = writer.getTextPos();
            for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
                var node = nodes_3[_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.getJsDocCommentsFromText(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, /*trailingSeparator*/ true, newLine, ts.writeCommentRange);
            }
        }
        function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) {
            writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
            emitType(type);
        }
        function emitType(type) {
            switch (type.kind) {
                case 117 /* AnyKeyword */:
                case 132 /* StringKeyword */:
                case 130 /* NumberKeyword */:
                case 120 /* BooleanKeyword */:
                case 133 /* SymbolKeyword */:
                case 103 /* VoidKeyword */:
                case 135 /* UndefinedKeyword */:
                case 93 /* NullKeyword */:
                case 127 /* NeverKeyword */:
                case 165 /* ThisType */:
                case 166 /* StringLiteralType */:
                    return writeTextOfNode(currentText, type);
                case 194 /* ExpressionWithTypeArguments */:
                    return emitExpressionWithTypeArguments(type);
                case 155 /* TypeReference */:
                    return emitTypeReference(type);
                case 158 /* TypeQuery */:
                    return emitTypeQuery(type);
                case 160 /* ArrayType */:
                    return emitArrayType(type);
                case 161 /* TupleType */:
                    return emitTupleType(type);
                case 162 /* UnionType */:
                    return emitUnionType(type);
                case 163 /* IntersectionType */:
                    return emitIntersectionType(type);
                case 164 /* ParenthesizedType */:
                    return emitParenType(type);
                case 156 /* FunctionType */:
                case 157 /* ConstructorType */:
                    return emitSignatureDeclarationWithJsDocComments(type);
                case 159 /* TypeLiteral */:
                    return emitTypeLiteral(type);
                case 69 /* Identifier */:
                    return emitEntityName(type);
                case 139 /* QualifiedName */:
                    return emitEntityName(type);
                case 154 /* TypePredicate */:
                    return emitTypePredicate(type);
            }
            function writeEntityName(entityName) {
                if (entityName.kind === 69 /* Identifier */) {
                    writeTextOfNode(currentText, entityName);
                }
                else {
                    var left = entityName.kind === 139 /* QualifiedName */ ? entityName.left : entityName.expression;
                    var right = entityName.kind === 139 /* 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 === 229 /* ImportEqualsDeclaration */ ? entityName.parent : enclosingDeclaration);
                handleSymbolAccessibilityError(visibilityResult);
                recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
                writeEntityName(entityName);
            }
            function emitExpressionWithTypeArguments(node) {
                if (ts.isSupportedExpressionWithTypeArguments(node)) {
                    ts.Debug.assert(node.expression.kind === 69 /* Identifier */ || node.expression.kind === 172 /* 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 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, true /* remove comments */);
            emitLines(node.statements);
        }
        // Return a temp variable name to be used in `export default` 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 getExportDefaultTempVariableName() {
            var baseName = "_default";
            if (!ts.hasProperty(currentIdentifiers, baseName)) {
                return baseName;
            }
            var count = 0;
            while (true) {
                count++;
                var name_23 = baseName + "_" + count;
                if (!ts.hasProperty(currentIdentifiers, name_23)) {
                    return name_23;
                }
            }
        }
        function emitExportAssignment(node) {
            if (node.expression.kind === 69 /* Identifier */) {
                write(node.isExportEquals ? "export = " : "export default ");
                writeTextOfNode(currentText, node.expression);
            }
            else {
                // Expression
                var tempVarName = getExportDefaultTempVariableName();
                if (!noDeclare) {
                    write("declare ");
                }
                write("var ");
                write(tempVarName);
                write(": ");
                writer.getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic;
                resolver.writeTypeOfExpression(node.expression, enclosingDeclaration, 2 /* UseTypeOfFunction */, writer);
                write(";");
                writeLine();
                write(node.isExportEquals ? "export = " : "export default ");
                write(tempVarName);
            }
            write(";");
            writeLine();
            // Make all the declarations visible for the export name
            if (node.expression.kind === 69 /* Identifier */) {
                var nodes = resolver.collectLinkedAliases(node.expression);
                // write each of these declarations asynchronously
                writeAsynchronousModuleElements(nodes);
            }
            function getDefaultExportAccessibilityDiagnostic(diagnostic) {
                return {
                    diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
                    errorNode: node
                };
            }
        }
        function isModuleElementVisible(node) {
            return resolver.isDeclarationVisible(node);
        }
        function emitModuleElement(node, isModuleElementVisible) {
            if (isModuleElementVisible) {
                writeModuleElement(node);
            }
            else if (node.kind === 229 /* ImportEqualsDeclaration */ ||
                (node.parent.kind === 256 /* SourceFile */ && isCurrentFileExternalModule)) {
                var isVisible = void 0;
                if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 256 /* 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 === 230 /* 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 220 /* FunctionDeclaration */:
                    return writeFunctionDeclaration(node);
                case 200 /* VariableStatement */:
                    return writeVariableStatement(node);
                case 222 /* InterfaceDeclaration */:
                    return writeInterfaceDeclaration(node);
                case 221 /* ClassDeclaration */:
                    return writeClassDeclaration(node);
                case 223 /* TypeAliasDeclaration */:
                    return writeTypeAliasDeclaration(node);
                case 224 /* EnumDeclaration */:
                    return writeEnumDeclaration(node);
                case 225 /* ModuleDeclaration */:
                    return writeModuleDeclaration(node);
                case 229 /* ImportEqualsDeclaration */:
                    return writeImportEqualsDeclaration(node);
                case 230 /* 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 === 256 /* SourceFile */) {
                // If the node is exported
                if (node.flags & 1 /* Export */) {
                    write("export ");
                }
                if (node.flags & 512 /* Default */) {
                    write("default ");
                }
                else if (node.kind !== 222 /* InterfaceDeclaration */ && !noDeclare) {
                    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 (node.flags & 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(symbolAccessibilityResult) {
                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 === 232 /* NamespaceImport */) {
                    return resolver.isDeclarationVisible(namedBindings);
                }
                else {
                    return ts.forEach(namedBindings.elements, function (namedImport) { return resolver.isDeclarationVisible(namedImport); });
                }
            }
        }
        function writeImportDeclaration(node) {
            emitJsDocComments(node);
            if (node.flags & 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 === 232 /* 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 !== 225 /* ModuleDeclaration */;
            var moduleSpecifier;
            if (parent.kind === 229 /* ImportEqualsDeclaration */) {
                var node = parent;
                moduleSpecifier = ts.getExternalModuleImportEqualsDeclarationExpression(node);
            }
            else if (parent.kind === 225 /* 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 & 4096 /* Namespace */) {
                    write("namespace ");
                }
                else {
                    write("module ");
                }
                if (ts.isExternalModuleAugmentation(node)) {
                    emitExternalModuleSpecifier(node);
                }
                else {
                    writeTextOfNode(currentText, node.name);
                }
            }
            while (node.body && node.body.kind !== 226 /* 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(symbolAccessibilityResult) {
                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(enumMemberValue.toString());
            }
            write(",");
            writeLine();
        }
        function isPrivateMethodTypeParameter(node) {
            return node.parent.kind === 147 /* MethodDeclaration */ && (node.parent.flags & 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 === 156 /* FunctionType */ ||
                        node.parent.kind === 157 /* ConstructorType */ ||
                        (node.parent.parent && node.parent.parent.kind === 159 /* TypeLiteral */)) {
                        ts.Debug.assert(node.parent.kind === 147 /* MethodDeclaration */ ||
                            node.parent.kind === 146 /* MethodSignature */ ||
                            node.parent.kind === 156 /* FunctionType */ ||
                            node.parent.kind === 157 /* ConstructorType */ ||
                            node.parent.kind === 151 /* CallSignature */ ||
                            node.parent.kind === 152 /* ConstructSignature */);
                        emitType(node.constraint);
                    }
                    else {
                        emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError);
                    }
                }
                function getTypeParameterConstraintVisibilityError(symbolAccessibilityResult) {
                    // Type parameter constraints are named by user so we should always be able to name it
                    var diagnosticMessage;
                    switch (node.parent.kind) {
                        case 221 /* ClassDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
                            break;
                        case 222 /* InterfaceDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
                            break;
                        case 152 /* ConstructSignature */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                            break;
                        case 151 /* CallSignature */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                            break;
                        case 147 /* MethodDeclaration */:
                        case 146 /* MethodSignature */:
                            if (node.parent.flags & 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 === 221 /* 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 220 /* FunctionDeclaration */:
                            diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_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.isSupportedExpressionWithTypeArguments(node)) {
                    emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
                }
                else if (!isImplementsList && node.expression.kind === 93 /* NullKeyword */) {
                    write("null");
                }
                else {
                    writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError;
                    resolver.writeBaseConstructorTypeOfClass(enclosingDeclaration, enclosingDeclaration, 2 /* UseTypeOfFunction */, writer);
                }
                function getHeritageClauseVisibilityError(symbolAccessibilityResult) {
                    var diagnosticMessage;
                    // Heritage clause is written by user so it can always be named
                    if (node.parent.parent.kind === 221 /* 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: node.parent.parent.name
                    };
                }
            }
        }
        function writeClassDeclaration(node) {
            function emitParameterProperties(constructorDeclaration) {
                if (constructorDeclaration) {
                    ts.forEach(constructorDeclaration.parameters, function (param) {
                        if (param.flags & 92 /* ParameterPropertyModifier */) {
                            emitPropertyDeclaration(param);
                        }
                    });
                }
            }
            emitJsDocComments(node);
            emitModuleElementDeclarationFlags(node);
            if (node.flags & 128 /* Abstract */) {
                write("abstract ");
            }
            write("class ");
            writeTextOfNode(currentText, node.name);
            var prevEnclosingDeclaration = enclosingDeclaration;
            enclosingDeclaration = node;
            emitTypeParameters(node.typeParameters);
            var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
            if (baseTypeNode) {
                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);
            emitHeritageClause(ts.getInterfaceBaseTypeNodes(node), /*isImplementsList*/ false);
            write(" {");
            writeLine();
            increaseIndent();
            emitLines(node.members);
            decreaseIndent();
            write("}");
            writeLine();
            enclosingDeclaration = prevEnclosingDeclaration;
        }
        function emitPropertyDeclaration(node) {
            if (ts.hasDynamicName(node)) {
                return;
            }
            emitJsDocComments(node);
            emitClassMemberDeclarationFlags(node.flags);
            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 !== 218 /* 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 ?
                    if ((node.kind === 145 /* PropertyDeclaration */ || node.kind === 144 /* PropertySignature */ || node.kind === 142 /* Parameter */) && ts.hasQuestionToken(node)) {
                        write("?");
                    }
                    if ((node.kind === 145 /* PropertyDeclaration */ || node.kind === 144 /* PropertySignature */) && node.parent.kind === 159 /* TypeLiteral */) {
                        emitTypeOfVariableDeclarationFromTypeLiteral(node);
                    }
                    else if (!(node.flags & 8 /* Private */)) {
                        writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
                    }
                }
            }
            function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
                if (node.kind === 218 /* 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 === 145 /* PropertyDeclaration */ || node.kind === 144 /* PropertySignature */) {
                    // TODO(jfreeman): Deal with computed properties in error reporting.
                    if (node.flags & 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 === 221 /* ClassDeclaration */) {
                        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 !== 193 /* 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) {
            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(node.flags | (accessors.setAccessor ? 0 : 64 /* Readonly */));
                writeTextOfNode(currentText, node.name);
                if (!(node.flags & 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 === 149 /* 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 === 149 /* 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 === 150 /* SetAccessor */) {
                    // Setters have to have type named and cannot infer it so, the type should always be named
                    if (accessorWithTypeAnnotation.parent.flags & 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 (accessorWithTypeAnnotation.flags & 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 === 220 /* FunctionDeclaration */) {
                    emitModuleElementDeclarationFlags(node);
                }
                else if (node.kind === 147 /* MethodDeclaration */ || node.kind === 148 /* Constructor */) {
                    emitClassMemberDeclarationFlags(node.flags);
                }
                if (node.kind === 220 /* FunctionDeclaration */) {
                    write("function ");
                    writeTextOfNode(currentText, node.name);
                }
                else if (node.kind === 148 /* 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 === 153 /* IndexSignature */) {
                // Index signature can have readonly modifier
                emitClassMemberDeclarationFlags(node.flags);
                write("[");
            }
            else {
                // Construct signature or constructor type write new Signature
                if (node.kind === 152 /* ConstructSignature */ || node.kind === 157 /* ConstructorType */) {
                    write("new ");
                }
                else if (node.kind === 156 /* 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 === 153 /* IndexSignature */) {
                write("]");
            }
            else {
                write(")");
            }
            // If this is not a constructor and is not private, emit the return type
            var isFunctionTypeOrConstructorType = node.kind === 156 /* FunctionType */ || node.kind === 157 /* ConstructorType */;
            if (isFunctionTypeOrConstructorType || node.parent.kind === 159 /* TypeLiteral */) {
                // Emit type literal signature return type only if specified
                if (node.type) {
                    write(isFunctionTypeOrConstructorType ? " => " : ": ");
                    emitType(node.type);
                }
            }
            else if (node.kind !== 148 /* Constructor */ && !(node.flags & 8 /* Private */)) {
                writeReturnTypeAtSignature(node, getReturnTypeVisibilityError);
            }
            enclosingDeclaration = prevEnclosingDeclaration;
            if (!isFunctionTypeOrConstructorType) {
                write(";");
                writeLine();
            }
            else if (closeParenthesizedFunctionType) {
                write(")");
            }
            function getReturnTypeVisibilityError(symbolAccessibilityResult) {
                var diagnosticMessage;
                switch (node.kind) {
                    case 152 /* 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 151 /* 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 153 /* 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 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                        if (node.flags & 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 === 221 /* 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 220 /* 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 === 156 /* FunctionType */ ||
                node.parent.kind === 157 /* ConstructorType */ ||
                node.parent.parent.kind === 159 /* TypeLiteral */) {
                emitTypeOfVariableDeclarationFromTypeLiteral(node);
            }
            else if (!(node.parent.flags & 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 148 /* 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 152 /* 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 151 /* 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 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                        if (node.parent.flags & 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 === 221 /* 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 220 /* 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 === 167 /* ObjectBindingPattern */) {
                    write("{");
                    emitCommaList(bindingPattern.elements, emitBindingElement);
                    write("}");
                }
                else if (bindingPattern.kind === 168 /* ArrayBindingPattern */) {
                    write("[");
                    var elements = bindingPattern.elements;
                    emitCommaList(elements, emitBindingElement);
                    if (elements && elements.hasTrailingComma) {
                        write(", ");
                    }
                    write("]");
                }
            }
            function emitBindingElement(bindingElement) {
                if (bindingElement.kind === 193 /* 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 === 169 /* 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 === 69 /* 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 220 /* FunctionDeclaration */:
                case 225 /* ModuleDeclaration */:
                case 229 /* ImportEqualsDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 221 /* ClassDeclaration */:
                case 223 /* TypeAliasDeclaration */:
                case 224 /* EnumDeclaration */:
                    return emitModuleElement(node, isModuleElementVisible(node));
                case 200 /* VariableStatement */:
                    return emitModuleElement(node, isVariableStatementVisible(node));
                case 230 /* ImportDeclaration */:
                    // Import declaration without import clause is visible, otherwise it is not visible
                    return emitModuleElement(node, /*isModuleElementVisible*/ !node.importClause);
                case 236 /* ExportDeclaration */:
                    return emitExportDeclaration(node);
                case 148 /* Constructor */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                    return writeFunctionDeclaration(node);
                case 152 /* ConstructSignature */:
                case 151 /* CallSignature */:
                case 153 /* IndexSignature */:
                    return emitSignatureDeclarationWithJsDocComments(node);
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                    return emitAccessorDeclaration(node);
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                    return emitPropertyDeclaration(node);
                case 255 /* EnumMember */:
                    return emitEnumMemberDeclaration(node);
                case 235 /* ExportAssignment */:
                    return emitExportAssignment(node);
                case 256 /* 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) {
            var declFileName;
            var addedBundledEmitReference = false;
            if (ts.isDeclarationFile(referencedFile)) {
                // Declaration file, use declaration file name
                declFileName = referencedFile.fileName;
            }
            else {
                // Get the declaration file path
                ts.forEachExpectedEmitFile(host, getDeclFileName, referencedFile);
            }
            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, sourceFiles, isBundledEmit) {
                // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
                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, sourceFiles, isBundledEmit, host, resolver, emitterDiagnostics) {
        var emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit);
        var emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
        if (!emitSkipped) {
            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="sourcemap.ts" />
/// <reference path="declarationEmitter.ts"/>
/* @internal */
var ts;
(function (ts) {
    function getResolvedExternalModuleName(host, file) {
        return file.moduleName || ts.getExternalModuleNameFromPath(host, file.fileName);
    }
    ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
    function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
        var file = resolver.getExternalModuleFileFromDeclaration(declaration);
        if (!file || ts.isDeclarationFile(file)) {
            return undefined;
        }
        return getResolvedExternalModuleName(host, file);
    }
    ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
    var Jump;
    (function (Jump) {
        Jump[Jump["Break"] = 2] = "Break";
        Jump[Jump["Continue"] = 4] = "Continue";
        Jump[Jump["Return"] = 8] = "Return";
    })(Jump || (Jump = {}));
    var entities = {
        "quot": 0x0022,
        "amp": 0x0026,
        "apos": 0x0027,
        "lt": 0x003C,
        "gt": 0x003E,
        "nbsp": 0x00A0,
        "iexcl": 0x00A1,
        "cent": 0x00A2,
        "pound": 0x00A3,
        "curren": 0x00A4,
        "yen": 0x00A5,
        "brvbar": 0x00A6,
        "sect": 0x00A7,
        "uml": 0x00A8,
        "copy": 0x00A9,
        "ordf": 0x00AA,
        "laquo": 0x00AB,
        "not": 0x00AC,
        "shy": 0x00AD,
        "reg": 0x00AE,
        "macr": 0x00AF,
        "deg": 0x00B0,
        "plusmn": 0x00B1,
        "sup2": 0x00B2,
        "sup3": 0x00B3,
        "acute": 0x00B4,
        "micro": 0x00B5,
        "para": 0x00B6,
        "middot": 0x00B7,
        "cedil": 0x00B8,
        "sup1": 0x00B9,
        "ordm": 0x00BA,
        "raquo": 0x00BB,
        "frac14": 0x00BC,
        "frac12": 0x00BD,
        "frac34": 0x00BE,
        "iquest": 0x00BF,
        "Agrave": 0x00C0,
        "Aacute": 0x00C1,
        "Acirc": 0x00C2,
        "Atilde": 0x00C3,
        "Auml": 0x00C4,
        "Aring": 0x00C5,
        "AElig": 0x00C6,
        "Ccedil": 0x00C7,
        "Egrave": 0x00C8,
        "Eacute": 0x00C9,
        "Ecirc": 0x00CA,
        "Euml": 0x00CB,
        "Igrave": 0x00CC,
        "Iacute": 0x00CD,
        "Icirc": 0x00CE,
        "Iuml": 0x00CF,
        "ETH": 0x00D0,
        "Ntilde": 0x00D1,
        "Ograve": 0x00D2,
        "Oacute": 0x00D3,
        "Ocirc": 0x00D4,
        "Otilde": 0x00D5,
        "Ouml": 0x00D6,
        "times": 0x00D7,
        "Oslash": 0x00D8,
        "Ugrave": 0x00D9,
        "Uacute": 0x00DA,
        "Ucirc": 0x00DB,
        "Uuml": 0x00DC,
        "Yacute": 0x00DD,
        "THORN": 0x00DE,
        "szlig": 0x00DF,
        "agrave": 0x00E0,
        "aacute": 0x00E1,
        "acirc": 0x00E2,
        "atilde": 0x00E3,
        "auml": 0x00E4,
        "aring": 0x00E5,
        "aelig": 0x00E6,
        "ccedil": 0x00E7,
        "egrave": 0x00E8,
        "eacute": 0x00E9,
        "ecirc": 0x00EA,
        "euml": 0x00EB,
        "igrave": 0x00EC,
        "iacute": 0x00ED,
        "icirc": 0x00EE,
        "iuml": 0x00EF,
        "eth": 0x00F0,
        "ntilde": 0x00F1,
        "ograve": 0x00F2,
        "oacute": 0x00F3,
        "ocirc": 0x00F4,
        "otilde": 0x00F5,
        "ouml": 0x00F6,
        "divide": 0x00F7,
        "oslash": 0x00F8,
        "ugrave": 0x00F9,
        "uacute": 0x00FA,
        "ucirc": 0x00FB,
        "uuml": 0x00FC,
        "yacute": 0x00FD,
        "thorn": 0x00FE,
        "yuml": 0x00FF,
        "OElig": 0x0152,
        "oelig": 0x0153,
        "Scaron": 0x0160,
        "scaron": 0x0161,
        "Yuml": 0x0178,
        "fnof": 0x0192,
        "circ": 0x02C6,
        "tilde": 0x02DC,
        "Alpha": 0x0391,
        "Beta": 0x0392,
        "Gamma": 0x0393,
        "Delta": 0x0394,
        "Epsilon": 0x0395,
        "Zeta": 0x0396,
        "Eta": 0x0397,
        "Theta": 0x0398,
        "Iota": 0x0399,
        "Kappa": 0x039A,
        "Lambda": 0x039B,
        "Mu": 0x039C,
        "Nu": 0x039D,
        "Xi": 0x039E,
        "Omicron": 0x039F,
        "Pi": 0x03A0,
        "Rho": 0x03A1,
        "Sigma": 0x03A3,
        "Tau": 0x03A4,
        "Upsilon": 0x03A5,
        "Phi": 0x03A6,
        "Chi": 0x03A7,
        "Psi": 0x03A8,
        "Omega": 0x03A9,
        "alpha": 0x03B1,
        "beta": 0x03B2,
        "gamma": 0x03B3,
        "delta": 0x03B4,
        "epsilon": 0x03B5,
        "zeta": 0x03B6,
        "eta": 0x03B7,
        "theta": 0x03B8,
        "iota": 0x03B9,
        "kappa": 0x03BA,
        "lambda": 0x03BB,
        "mu": 0x03BC,
        "nu": 0x03BD,
        "xi": 0x03BE,
        "omicron": 0x03BF,
        "pi": 0x03C0,
        "rho": 0x03C1,
        "sigmaf": 0x03C2,
        "sigma": 0x03C3,
        "tau": 0x03C4,
        "upsilon": 0x03C5,
        "phi": 0x03C6,
        "chi": 0x03C7,
        "psi": 0x03C8,
        "omega": 0x03C9,
        "thetasym": 0x03D1,
        "upsih": 0x03D2,
        "piv": 0x03D6,
        "ensp": 0x2002,
        "emsp": 0x2003,
        "thinsp": 0x2009,
        "zwnj": 0x200C,
        "zwj": 0x200D,
        "lrm": 0x200E,
        "rlm": 0x200F,
        "ndash": 0x2013,
        "mdash": 0x2014,
        "lsquo": 0x2018,
        "rsquo": 0x2019,
        "sbquo": 0x201A,
        "ldquo": 0x201C,
        "rdquo": 0x201D,
        "bdquo": 0x201E,
        "dagger": 0x2020,
        "Dagger": 0x2021,
        "bull": 0x2022,
        "hellip": 0x2026,
        "permil": 0x2030,
        "prime": 0x2032,
        "Prime": 0x2033,
        "lsaquo": 0x2039,
        "rsaquo": 0x203A,
        "oline": 0x203E,
        "frasl": 0x2044,
        "euro": 0x20AC,
        "image": 0x2111,
        "weierp": 0x2118,
        "real": 0x211C,
        "trade": 0x2122,
        "alefsym": 0x2135,
        "larr": 0x2190,
        "uarr": 0x2191,
        "rarr": 0x2192,
        "darr": 0x2193,
        "harr": 0x2194,
        "crarr": 0x21B5,
        "lArr": 0x21D0,
        "uArr": 0x21D1,
        "rArr": 0x21D2,
        "dArr": 0x21D3,
        "hArr": 0x21D4,
        "forall": 0x2200,
        "part": 0x2202,
        "exist": 0x2203,
        "empty": 0x2205,
        "nabla": 0x2207,
        "isin": 0x2208,
        "notin": 0x2209,
        "ni": 0x220B,
        "prod": 0x220F,
        "sum": 0x2211,
        "minus": 0x2212,
        "lowast": 0x2217,
        "radic": 0x221A,
        "prop": 0x221D,
        "infin": 0x221E,
        "ang": 0x2220,
        "and": 0x2227,
        "or": 0x2228,
        "cap": 0x2229,
        "cup": 0x222A,
        "int": 0x222B,
        "there4": 0x2234,
        "sim": 0x223C,
        "cong": 0x2245,
        "asymp": 0x2248,
        "ne": 0x2260,
        "equiv": 0x2261,
        "le": 0x2264,
        "ge": 0x2265,
        "sub": 0x2282,
        "sup": 0x2283,
        "nsub": 0x2284,
        "sube": 0x2286,
        "supe": 0x2287,
        "oplus": 0x2295,
        "otimes": 0x2297,
        "perp": 0x22A5,
        "sdot": 0x22C5,
        "lceil": 0x2308,
        "rceil": 0x2309,
        "lfloor": 0x230A,
        "rfloor": 0x230B,
        "lang": 0x2329,
        "rang": 0x232A,
        "loz": 0x25CA,
        "spades": 0x2660,
        "clubs": 0x2663,
        "hearts": 0x2665,
        "diams": 0x2666
    };
    // Flags enum to track count of temp variables and a few dedicated names
    var TempFlags;
    (function (TempFlags) {
        TempFlags[TempFlags["Auto"] = 0] = "Auto";
        TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
        TempFlags[TempFlags["_i"] = 268435456] = "_i";
    })(TempFlags || (TempFlags = {}));
    var CopyDirection;
    (function (CopyDirection) {
        CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal";
        CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter";
    })(CopyDirection || (CopyDirection = {}));
    // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
    function emitFiles(resolver, host, targetSourceFile) {
        // emit output for the __extends helper function
        var extendsHelper = "\nvar __extends = (this && this.__extends) || function (d, b) {\n    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];\n    function __() { this.constructor = d; }\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n};";
        var assignHelper = "\nvar __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};";
        // emit output for the __decorate helper function
        var decorateHelper = "\nvar __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};";
        // emit output for the __metadata helper function
        var metadataHelper = "\nvar __metadata = (this && this.__metadata) || function (k, v) {\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n};";
        // emit output for the __param helper function
        var paramHelper = "\nvar __param = (this && this.__param) || function (paramIndex, decorator) {\n    return function (target, key) { decorator(target, key, paramIndex); }\n};";
        var awaiterHelper = "\nvar __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};";
        var compilerOptions = host.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var modulekind = ts.getEmitModuleKind(compilerOptions);
        var sourceMapDataList = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
        var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined;
        var emitterDiagnostics = ts.createDiagnosticCollection();
        var emitSkipped = false;
        var newLine = host.getNewLine();
        var emitJavaScript = createFileEmitter();
        ts.forEachExpectedEmitFile(host, emitFile, targetSourceFile);
        return {
            emitSkipped: emitSkipped,
            diagnostics: emitterDiagnostics.getDiagnostics(),
            emittedFiles: emittedFilesList,
            sourceMaps: sourceMapDataList
        };
        function isUniqueLocalName(name, container) {
            for (var node = container; ts.isNodeDescendentOf(node, container); node = node.nextContainer) {
                if (node.locals && ts.hasProperty(node.locals, name)) {
                    // We conservatively include alias symbols to cover cases where they're emitted as locals
                    if (node.locals[name].flags & (107455 /* Value */ | 1048576 /* ExportValue */ | 8388608 /* Alias */)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function setLabeledJump(state, isBreak, labelText, labelMarker) {
            if (isBreak) {
                if (!state.labeledNonLocalBreaks) {
                    state.labeledNonLocalBreaks = {};
                }
                state.labeledNonLocalBreaks[labelText] = labelMarker;
            }
            else {
                if (!state.labeledNonLocalContinues) {
                    state.labeledNonLocalContinues = {};
                }
                state.labeledNonLocalContinues[labelText] = labelMarker;
            }
        }
        function hoistVariableDeclarationFromLoop(state, declaration) {
            if (!state.hoistedLocalVariables) {
                state.hoistedLocalVariables = [];
            }
            visit(declaration.name);
            function visit(node) {
                if (node.kind === 69 /* Identifier */) {
                    state.hoistedLocalVariables.push(node);
                }
                else {
                    for (var _a = 0, _b = node.elements; _a < _b.length; _a++) {
                        var element = _b[_a];
                        visit(element.name);
                    }
                }
            }
        }
        function createFileEmitter() {
            var writer = ts.createTextWriter(newLine);
            var write = writer.write, writeTextOfNode = writer.writeTextOfNode, writeLine = writer.writeLine, increaseIndent = writer.increaseIndent, decreaseIndent = writer.decreaseIndent;
            var sourceMap = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? ts.createSourceMapWriter(host, writer) : ts.getNullSourceMapWriter();
            var setSourceFile = sourceMap.setSourceFile, emitStart = sourceMap.emitStart, emitEnd = sourceMap.emitEnd, emitPos = sourceMap.emitPos;
            var currentSourceFile;
            var currentText;
            var currentLineMap;
            var currentFileIdentifiers;
            var renamedDependencies;
            var isEs6Module;
            var isCurrentFileExternalModule;
            // name of an exporter function if file is a System external module
            // System.register([...], function (<exporter>) {...})
            // exporting in System modules looks like:
            // export var x; ... x = 1
            // =>
            // var x;... exporter("x", x = 1)
            var exportFunctionForFile;
            var contextObjectForFile;
            var generatedNameSet;
            var nodeToGeneratedName;
            var computedPropertyNamesToGeneratedNames;
            var decoratedClassAliases;
            var convertedLoopState;
            var extendsEmitted;
            var assignEmitted;
            var decorateEmitted;
            var paramEmitted;
            var awaiterEmitted;
            var tempFlags = 0;
            var tempVariables;
            var tempParameters;
            var externalImports;
            var exportSpecifiers;
            var exportEquals;
            var hasExportStarsToExportValues;
            var detachedCommentsInfo;
            /** Sourcemap data that will get encoded */
            var sourceMapData;
            /** Is the file being emitted into its own file */
            var isOwnFileEmit;
            /** If removeComments is true, no leading-comments needed to be emitted **/
            var emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos) { } : emitLeadingCommentsOfPositionWorker;
            var setSourceMapWriterEmit = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? changeSourceMapEmit : function (writer) { };
            var moduleEmitDelegates = (_a = {},
                _a[ts.ModuleKind.ES6] = emitES6Module,
                _a[ts.ModuleKind.AMD] = emitAMDModule,
                _a[ts.ModuleKind.System] = emitSystemModule,
                _a[ts.ModuleKind.UMD] = emitUMDModule,
                _a[ts.ModuleKind.CommonJS] = emitCommonJSModule,
                _a
            );
            var bundleEmitDelegates = (_b = {},
                _b[ts.ModuleKind.ES6] = function () { },
                _b[ts.ModuleKind.AMD] = emitAMDModule,
                _b[ts.ModuleKind.System] = emitSystemModule,
                _b[ts.ModuleKind.UMD] = function () { },
                _b[ts.ModuleKind.CommonJS] = function () { },
                _b
            );
            return doEmit;
            function doEmit(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit) {
                sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
                generatedNameSet = {};
                nodeToGeneratedName = [];
                decoratedClassAliases = [];
                isOwnFileEmit = !isBundledEmit;
                // Emit helpers from all the files
                if (isBundledEmit && modulekind) {
                    ts.forEach(sourceFiles, emitEmitHelpers);
                }
                // Do not call emit directly. It does not set the currentSourceFile.
                ts.forEach(sourceFiles, emitSourceFile);
                writeLine();
                var sourceMappingURL = sourceMap.getSourceMappingURL();
                if (sourceMappingURL) {
                    write("//# sourceMappingURL=" + sourceMappingURL);
                }
                writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM, sourceFiles);
                // reset the state
                sourceMap.reset();
                writer.reset();
                currentSourceFile = undefined;
                currentText = undefined;
                currentLineMap = undefined;
                exportFunctionForFile = undefined;
                contextObjectForFile = undefined;
                generatedNameSet = undefined;
                nodeToGeneratedName = undefined;
                decoratedClassAliases = undefined;
                computedPropertyNamesToGeneratedNames = undefined;
                convertedLoopState = undefined;
                extendsEmitted = false;
                decorateEmitted = false;
                paramEmitted = false;
                awaiterEmitted = false;
                assignEmitted = false;
                tempFlags = 0;
                tempVariables = undefined;
                tempParameters = undefined;
                externalImports = undefined;
                exportSpecifiers = undefined;
                exportEquals = undefined;
                hasExportStarsToExportValues = undefined;
                detachedCommentsInfo = undefined;
                sourceMapData = undefined;
                isEs6Module = false;
                renamedDependencies = undefined;
                isCurrentFileExternalModule = false;
            }
            function emitSourceFile(sourceFile) {
                currentSourceFile = sourceFile;
                currentText = sourceFile.text;
                currentLineMap = ts.getLineStarts(sourceFile);
                exportFunctionForFile = undefined;
                contextObjectForFile = undefined;
                isEs6Module = sourceFile.symbol && sourceFile.symbol.exports && !!sourceFile.symbol.exports["___esModule"];
                renamedDependencies = sourceFile.renamedDependencies;
                currentFileIdentifiers = sourceFile.identifiers;
                isCurrentFileExternalModule = ts.isExternalModule(sourceFile);
                setSourceFile(sourceFile);
                emitNodeWithCommentsAndWithoutSourcemap(sourceFile);
            }
            function isUniqueName(name) {
                return !resolver.hasGlobalName(name) &&
                    !ts.hasProperty(currentFileIdentifiers, name) &&
                    !ts.hasProperty(generatedNameSet, name);
            }
            // Return the next available name in the pattern _a ... _z, _0, _1, ...
            // TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
            // Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
            function makeTempVariableName(flags) {
                if (flags && !(tempFlags & flags)) {
                    var name_24 = flags === 268435456 /* _i */ ? "_i" : "_n";
                    if (isUniqueName(name_24)) {
                        tempFlags |= flags;
                        return name_24;
                    }
                }
                while (true) {
                    var count = tempFlags & 268435455 /* CountMask */;
                    tempFlags++;
                    // Skip over 'i' and 'n'
                    if (count !== 8 && count !== 13) {
                        var name_25 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26);
                        if (isUniqueName(name_25)) {
                            return name_25;
                        }
                    }
                }
            }
            // Generate a name that is unique within the current file and doesn't conflict with any names
            // in global scope. The name is formed by adding an '_n' suffix to the specified base name,
            // where n is a positive integer. Note that names generated by makeTempVariableName and
            // makeUniqueName are guaranteed to never conflict.
            function makeUniqueName(baseName) {
                // Find the first unique 'name_n', where n is a positive number
                if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
                    baseName += "_";
                }
                var i = 1;
                while (true) {
                    var generatedName = baseName + i;
                    if (isUniqueName(generatedName)) {
                        return generatedNameSet[generatedName] = generatedName;
                    }
                    i++;
                }
            }
            function generateNameForModuleOrEnum(node) {
                var name = node.name.text;
                // Use module/enum name itself if it is unique, otherwise make a unique variation
                return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
            }
            function generateNameForImportOrExportDeclaration(node) {
                var expr = ts.getExternalModuleName(node);
                var baseName = expr.kind === 9 /* StringLiteral */ ?
                    ts.escapeIdentifier(ts.makeIdentifierFromModuleName(expr.text)) : "module";
                return makeUniqueName(baseName);
            }
            function generateNameForExportDefault() {
                return makeUniqueName("default");
            }
            function generateNameForClassExpression() {
                return makeUniqueName("class");
            }
            function generateNameForNode(node) {
                switch (node.kind) {
                    case 69 /* Identifier */:
                        return makeUniqueName(node.text);
                    case 225 /* ModuleDeclaration */:
                    case 224 /* EnumDeclaration */:
                        return generateNameForModuleOrEnum(node);
                    case 230 /* ImportDeclaration */:
                    case 236 /* ExportDeclaration */:
                        return generateNameForImportOrExportDeclaration(node);
                    case 220 /* FunctionDeclaration */:
                    case 221 /* ClassDeclaration */:
                    case 235 /* ExportAssignment */:
                        return generateNameForExportDefault();
                    case 192 /* ClassExpression */:
                        return generateNameForClassExpression();
                    default:
                        ts.Debug.fail();
                }
            }
            function getGeneratedNameForNode(node) {
                var id = ts.getNodeId(node);
                return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = ts.unescapeIdentifier(generateNameForNode(node)));
            }
            /** Write emitted output to disk */
            function writeEmittedFiles(emitOutput, jsFilePath, sourceMapFilePath, writeByteOrderMark, sourceFiles) {
                if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) {
                    ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles);
                }
                if (sourceMapDataList) {
                    sourceMapDataList.push(sourceMap.getSourceMapData());
                }
                ts.writeFile(host, emitterDiagnostics, jsFilePath, emitOutput, writeByteOrderMark, sourceFiles);
            }
            // Create a temporary variable with a unique unused name.
            function createTempVariable(flags) {
                var result = ts.createSynthesizedNode(69 /* Identifier */);
                result.text = makeTempVariableName(flags);
                return result;
            }
            function recordTempDeclaration(name) {
                if (!tempVariables) {
                    tempVariables = [];
                }
                tempVariables.push(name);
            }
            function createAndRecordTempVariable(flags) {
                var temp = createTempVariable(flags);
                recordTempDeclaration(temp);
                return temp;
            }
            function emitTempDeclarations(newLine) {
                if (tempVariables) {
                    if (newLine) {
                        writeLine();
                    }
                    else {
                        write(" ");
                    }
                    write("var ");
                    emitCommaList(tempVariables);
                    write(";");
                }
            }
            /** Emit the text for the given token that comes after startPos
              * This by default writes the text provided with the given tokenKind
              * but if optional emitFn callback is provided the text is emitted using the callback instead of default text
              * @param tokenKind the kind of the token to search and emit
              * @param startPos the position in the source to start searching for the token
              * @param emitFn if given will be invoked to emit the text instead of actual token emit */
            function emitToken(tokenKind, startPos, emitFn) {
                var tokenStartPos = ts.skipTrivia(currentText, startPos);
                emitPos(tokenStartPos);
                var tokenString = ts.tokenToString(tokenKind);
                if (emitFn) {
                    emitFn();
                }
                else {
                    write(tokenString);
                }
                var tokenEndPos = tokenStartPos + tokenString.length;
                emitPos(tokenEndPos);
                return tokenEndPos;
            }
            function emitOptional(prefix, node) {
                if (node) {
                    write(prefix);
                    emit(node);
                }
            }
            function emitParenthesizedIf(node, parenthesized) {
                if (parenthesized) {
                    write("(");
                }
                emit(node);
                if (parenthesized) {
                    write(")");
                }
            }
            function emitLinePreservingList(parent, nodes, allowTrailingComma, spacesBetweenBraces) {
                ts.Debug.assert(nodes.length > 0);
                increaseIndent();
                if (nodeStartPositionsAreOnSameLine(parent, nodes[0])) {
                    if (spacesBetweenBraces) {
                        write(" ");
                    }
                }
                else {
                    writeLine();
                }
                for (var i = 0, n = nodes.length; i < n; i++) {
                    if (i) {
                        if (nodeEndIsOnSameLineAsNodeStart(nodes[i - 1], nodes[i])) {
                            write(", ");
                        }
                        else {
                            write(",");
                            writeLine();
                        }
                    }
                    emit(nodes[i]);
                }
                if (nodes.hasTrailingComma && allowTrailingComma) {
                    write(",");
                }
                decreaseIndent();
                if (nodeEndPositionsAreOnSameLine(parent, ts.lastOrUndefined(nodes))) {
                    if (spacesBetweenBraces) {
                        write(" ");
                    }
                }
                else {
                    writeLine();
                }
            }
            function emitList(nodes, start, count, multiLine, trailingComma, leadingComma, noTrailingNewLine, emitNode) {
                if (!emitNode) {
                    emitNode = emit;
                }
                for (var i = 0; i < count; i++) {
                    if (multiLine) {
                        if (i || leadingComma) {
                            write(",");
                        }
                        writeLine();
                    }
                    else {
                        if (i || leadingComma) {
                            write(", ");
                        }
                    }
                    var node = nodes[start + i];
                    // This emitting is to make sure we emit following comment properly
                    //   ...(x, /*comment1*/ y)...
                    //         ^ => node.pos
                    // "comment1" is not considered leading comment for "y" but rather
                    // considered as trailing comment of the previous node.
                    emitTrailingCommentsOfPosition(node.pos);
                    emitNode(node);
                    leadingComma = true;
                }
                if (trailingComma) {
                    write(",");
                }
                if (multiLine && !noTrailingNewLine) {
                    writeLine();
                }
                return count;
            }
            function emitCommaList(nodes) {
                if (nodes) {
                    emitList(nodes, 0, nodes.length, /*multiLine*/ false, /*trailingComma*/ false);
                }
            }
            function emitLines(nodes) {
                emitLinesStartingAt(nodes, /*startIndex*/ 0);
            }
            function emitLinesStartingAt(nodes, startIndex) {
                for (var i = startIndex; i < nodes.length; i++) {
                    writeLine();
                    emit(nodes[i]);
                }
            }
            function isBinaryOrOctalIntegerLiteral(node, text) {
                if (node.kind === 8 /* NumericLiteral */ && text.length > 1) {
                    switch (text.charCodeAt(1)) {
                        case 98 /* b */:
                        case 66 /* B */:
                        case 111 /* o */:
                        case 79 /* O */:
                            return true;
                    }
                }
                return false;
            }
            function emitLiteral(node) {
                var text = getLiteralText(node);
                if ((compilerOptions.sourceMap || compilerOptions.inlineSourceMap) && (node.kind === 9 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
                    writer.writeLiteral(text);
                }
                else if (languageVersion < 2 /* ES6 */ && isBinaryOrOctalIntegerLiteral(node, text)) {
                    write(node.text);
                }
                else {
                    write(text);
                }
            }
            function getLiteralText(node) {
                // Any template literal or string literal with an extended escape
                // (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
                if (languageVersion < 2 /* ES6 */ && (ts.isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
                    return getQuotedEscapedLiteralText('"', node.text, '"');
                }
                // If we don't need to downlevel and we can reach the original source text using
                // the node's parent reference, then simply get the text as it was originally written.
                if (node.parent) {
                    return ts.getTextOfNodeFromSourceText(currentText, node);
                }
                // If we can't reach the original source text, use the canonical form if it's a number,
                // or an escaped quoted form of the original text if it's string-like.
                switch (node.kind) {
                    case 9 /* StringLiteral */:
                        return getQuotedEscapedLiteralText('"', node.text, '"');
                    case 11 /* NoSubstitutionTemplateLiteral */:
                        return getQuotedEscapedLiteralText("`", node.text, "`");
                    case 12 /* TemplateHead */:
                        return getQuotedEscapedLiteralText("`", node.text, "${");
                    case 13 /* TemplateMiddle */:
                        return getQuotedEscapedLiteralText("}", node.text, "${");
                    case 14 /* TemplateTail */:
                        return getQuotedEscapedLiteralText("}", node.text, "`");
                    case 8 /* NumericLiteral */:
                        return node.text;
                }
                ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
            }
            function getQuotedEscapedLiteralText(leftQuote, text, rightQuote) {
                return leftQuote + ts.escapeNonAsciiCharacters(ts.escapeString(text)) + rightQuote;
            }
            function emitDownlevelRawTemplateLiteral(node) {
                // Find original source text, since we need to emit the raw strings of the tagged template.
                // The raw strings contain the (escaped) strings of what the user wrote.
                // Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
                var text = ts.getTextOfNodeFromSourceText(currentText, node);
                // text contains the original source, it will also contain quotes ("`"), dollar 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 === 11 /* NoSubstitutionTemplateLiteral */ || node.kind === 14 /* 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");
                text = ts.escapeString(text);
                write("\"" + text + "\"");
            }
            function emitDownlevelTaggedTemplateArray(node, literalEmitter) {
                write("[");
                if (node.template.kind === 11 /* NoSubstitutionTemplateLiteral */) {
                    literalEmitter(node.template);
                }
                else {
                    literalEmitter(node.template.head);
                    ts.forEach(node.template.templateSpans, function (child) {
                        write(", ");
                        literalEmitter(child.literal);
                    });
                }
                write("]");
            }
            function emitDownlevelTaggedTemplate(node) {
                var tempVariable = createAndRecordTempVariable(0 /* Auto */);
                write("(");
                emit(tempVariable);
                write(" = ");
                emitDownlevelTaggedTemplateArray(node, emit);
                write(", ");
                emit(tempVariable);
                write(".raw = ");
                emitDownlevelTaggedTemplateArray(node, emitDownlevelRawTemplateLiteral);
                write(", ");
                emitParenthesizedIf(node.tag, needsParenthesisForPropertyAccessOrInvocation(node.tag));
                write("(");
                emit(tempVariable);
                // Now we emit the expressions
                if (node.template.kind === 189 /* TemplateExpression */) {
                    ts.forEach(node.template.templateSpans, function (templateSpan) {
                        write(", ");
                        var needsParens = templateSpan.expression.kind === 187 /* BinaryExpression */
                            && templateSpan.expression.operatorToken.kind === 24 /* CommaToken */;
                        emitParenthesizedIf(templateSpan.expression, needsParens);
                    });
                }
                write("))");
            }
            function emitTemplateExpression(node) {
                // In ES6 mode and above, we can simply emit each portion of a template in order, but in
                // ES3 & ES5 we must convert the template expression into a series of string concatenations.
                if (languageVersion >= 2 /* ES6 */) {
                    ts.forEachChild(node, emit);
                    return;
                }
                var emitOuterParens = ts.isExpression(node.parent)
                    && templateNeedsParens(node, node.parent);
                if (emitOuterParens) {
                    write("(");
                }
                var headEmitted = false;
                if (shouldEmitTemplateHead()) {
                    emitLiteral(node.head);
                    headEmitted = true;
                }
                for (var i = 0, n = node.templateSpans.length; i < n; i++) {
                    var templateSpan = node.templateSpans[i];
                    // Check if the expression has operands and binds its operands less closely than binary '+'.
                    // If it does, we need to wrap the expression in parentheses. Otherwise, something like
                    //    `abc${ 1 << 2 }`
                    // becomes
                    //    "abc" + 1 << 2 + ""
                    // which is really
                    //    ("abc" + 1) << (2 + "")
                    // rather than
                    //    "abc" + (1 << 2) + ""
                    var needsParens = templateSpan.expression.kind !== 178 /* ParenthesizedExpression */
                        && comparePrecedenceToBinaryPlus(templateSpan.expression) !== 1 /* GreaterThan */;
                    if (i > 0 || headEmitted) {
                        // If this is the first span and the head was not emitted, then this templateSpan's
                        // expression will be the first to be emitted. Don't emit the preceding ' + ' in that
                        // case.
                        write(" + ");
                    }
                    emitParenthesizedIf(templateSpan.expression, needsParens);
                    // Only emit if the literal is non-empty.
                    // The binary '+' operator is left-associative, so the first string concatenation
                    // with the head will force the result up to this point to be a string.
                    // Emitting a '+ ""' has no semantic effect for middles and tails.
                    if (templateSpan.literal.text.length !== 0) {
                        write(" + ");
                        emitLiteral(templateSpan.literal);
                    }
                }
                if (emitOuterParens) {
                    write(")");
                }
                function shouldEmitTemplateHead() {
                    // If this expression has an empty head literal and the first template span has a non-empty
                    // literal, then emitting the empty head literal is not necessary.
                    //     `${ foo } and ${ bar }`
                    // can be emitted as
                    //     foo + " and " + bar
                    // This is because it is only required that one of the first two operands in the emit
                    // output must be a string literal, so that the other operand and all following operands
                    // are forced into strings.
                    //
                    // If the first template span has an empty literal, then the head must still be emitted.
                    //     `${ foo }${ bar }`
                    // must still be emitted as
                    //     "" + foo + bar
                    // There is always atleast one templateSpan in this code path, since
                    // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
                    ts.Debug.assert(node.templateSpans.length !== 0);
                    return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
                }
                function templateNeedsParens(template, parent) {
                    switch (parent.kind) {
                        case 174 /* CallExpression */:
                        case 175 /* NewExpression */:
                            return parent.expression === template;
                        case 176 /* TaggedTemplateExpression */:
                        case 178 /* ParenthesizedExpression */:
                            return false;
                        default:
                            return comparePrecedenceToBinaryPlus(parent) !== -1 /* LessThan */;
                    }
                }
                /**
                 * Returns whether the expression has lesser, greater,
                 * or equal precedence to the binary '+' operator
                 */
                function comparePrecedenceToBinaryPlus(expression) {
                    // All binary expressions have lower precedence than '+' apart from '*', '/', and '%'
                    // which have greater precedence and '-' which has equal precedence.
                    // All unary operators have a higher precedence apart from yield.
                    // Arrow functions and conditionals have a lower precedence,
                    // although we convert the former into regular function expressions in ES5 mode,
                    // and in ES6 mode this function won't get called anyway.
                    //
                    // TODO (drosen): Note that we need to account for the upcoming 'yield' and
                    //                spread ('...') unary operators that are anticipated for ES6.
                    switch (expression.kind) {
                        case 187 /* BinaryExpression */:
                            switch (expression.operatorToken.kind) {
                                case 37 /* AsteriskToken */:
                                case 39 /* SlashToken */:
                                case 40 /* PercentToken */:
                                    return 1 /* GreaterThan */;
                                case 35 /* PlusToken */:
                                case 36 /* MinusToken */:
                                    return 0 /* EqualTo */;
                                default:
                                    return -1 /* LessThan */;
                            }
                        case 190 /* YieldExpression */:
                        case 188 /* ConditionalExpression */:
                            return -1 /* LessThan */;
                        default:
                            return 1 /* GreaterThan */;
                    }
                }
            }
            function emitTemplateSpan(span) {
                emit(span.expression);
                emit(span.literal);
            }
            function jsxEmitReact(node) {
                /// Emit a tag name, which is either '"div"' for lower-cased names, or
                /// 'Div' for upper-cased or dotted names
                function emitTagName(name) {
                    if (name.kind === 69 /* Identifier */ && ts.isIntrinsicJsxName(name.text)) {
                        write('"');
                        emit(name);
                        write('"');
                    }
                    else {
                        emit(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 emitAttributeName(name) {
                    if (/^[A-Za-z_]\w*$/.test(name.text)) {
                        emit(name);
                    }
                    else {
                        write('"');
                        emit(name);
                        write('"');
                    }
                }
                /// Emit an name/value pair for an attribute (e.g. "x: 3")
                function emitJsxAttribute(node) {
                    emitAttributeName(node.name);
                    write(": ");
                    if (node.initializer) {
                        emit(node.initializer);
                    }
                    else {
                        write("true");
                    }
                }
                function emitJsxElement(openingNode, children) {
                    var syntheticReactRef = ts.createSynthesizedNode(69 /* Identifier */);
                    syntheticReactRef.text = compilerOptions.reactNamespace ? compilerOptions.reactNamespace : "React";
                    syntheticReactRef.parent = openingNode;
                    // Call React.createElement(tag, ...
                    emitLeadingComments(openingNode);
                    emitExpressionIdentifier(syntheticReactRef);
                    write(".createElement(");
                    emitTagName(openingNode.tagName);
                    write(", ");
                    // Attribute list
                    if (openingNode.attributes.length === 0) {
                        // When there are no attributes, React wants "null"
                        write("null");
                    }
                    else {
                        // Either emit one big object literal (no spread attribs), or
                        // a call to the __assign helper
                        var attrs = openingNode.attributes;
                        if (ts.forEach(attrs, function (attr) { return attr.kind === 247 /* JsxSpreadAttribute */; })) {
                            write("__assign(");
                            var haveOpenedObjectLiteral = false;
                            for (var i = 0; i < attrs.length; i++) {
                                if (attrs[i].kind === 247 /* JsxSpreadAttribute */) {
                                    // If this is the first argument, we need to emit a {} as the first argument
                                    if (i === 0) {
                                        write("{}, ");
                                    }
                                    if (haveOpenedObjectLiteral) {
                                        write("}");
                                        haveOpenedObjectLiteral = false;
                                    }
                                    if (i > 0) {
                                        write(", ");
                                    }
                                    emit(attrs[i].expression);
                                }
                                else {
                                    ts.Debug.assert(attrs[i].kind === 246 /* JsxAttribute */);
                                    if (haveOpenedObjectLiteral) {
                                        write(", ");
                                    }
                                    else {
                                        haveOpenedObjectLiteral = true;
                                        if (i > 0) {
                                            write(", ");
                                        }
                                        write("{");
                                    }
                                    emitJsxAttribute(attrs[i]);
                                }
                            }
                            if (haveOpenedObjectLiteral)
                                write("}");
                            write(")"); // closing paren to React.__spread(
                        }
                        else {
                            // One object literal with all the attributes in them
                            write("{");
                            for (var i = 0, n = attrs.length; i < n; i++) {
                                if (i > 0) {
                                    write(", ");
                                }
                                emitJsxAttribute(attrs[i]);
                            }
                            write("}");
                        }
                    }
                    // Children
                    if (children) {
                        var firstChild = void 0;
                        var multipleEmittableChildren = false;
                        for (var i = 0, n = children.length; i < n; i++) {
                            var jsxChild = children[i];
                            if (isJsxChildEmittable(jsxChild)) {
                                // we need to decide whether to emit in single line or multiple lines as indented list
                                // store firstChild reference, if we see another emittable child, then emit accordingly
                                if (!firstChild) {
                                    write(", ");
                                    firstChild = jsxChild;
                                }
                                else {
                                    // more than one emittable child, emit indented list
                                    if (!multipleEmittableChildren) {
                                        multipleEmittableChildren = true;
                                        increaseIndent();
                                        writeLine();
                                        emit(firstChild);
                                    }
                                    write(", ");
                                    writeLine();
                                    emit(jsxChild);
                                }
                            }
                        }
                        if (multipleEmittableChildren) {
                            decreaseIndent();
                        }
                        else if (firstChild) {
                            if (firstChild.kind !== 241 /* JsxElement */ && firstChild.kind !== 242 /* JsxSelfClosingElement */) {
                                emit(firstChild);
                            }
                            else {
                                // If the only child is jsx element, put it on a new indented line
                                increaseIndent();
                                writeLine();
                                emit(firstChild);
                                writeLine();
                                decreaseIndent();
                            }
                        }
                    }
                    // Closing paren
                    write(")"); // closes "React.createElement("
                    emitTrailingComments(openingNode);
                }
                if (node.kind === 241 /* JsxElement */) {
                    emitJsxElement(node.openingElement, node.children);
                }
                else {
                    ts.Debug.assert(node.kind === 242 /* JsxSelfClosingElement */);
                    emitJsxElement(node);
                }
            }
            function jsxEmitPreserve(node) {
                function emitJsxAttribute(node) {
                    emit(node.name);
                    if (node.initializer) {
                        write("=");
                        emit(node.initializer);
                    }
                }
                function emitJsxSpreadAttribute(node) {
                    write("{...");
                    emit(node.expression);
                    write("}");
                }
                function emitAttributes(attribs) {
                    for (var i = 0, n = attribs.length; i < n; i++) {
                        if (i > 0) {
                            write(" ");
                        }
                        if (attribs[i].kind === 247 /* JsxSpreadAttribute */) {
                            emitJsxSpreadAttribute(attribs[i]);
                        }
                        else {
                            ts.Debug.assert(attribs[i].kind === 246 /* JsxAttribute */);
                            emitJsxAttribute(attribs[i]);
                        }
                    }
                }
                function emitJsxOpeningOrSelfClosingElement(node) {
                    write("<");
                    emit(node.tagName);
                    if (node.attributes.length > 0 || (node.kind === 242 /* JsxSelfClosingElement */)) {
                        write(" ");
                    }
                    emitAttributes(node.attributes);
                    if (node.kind === 242 /* JsxSelfClosingElement */) {
                        write("/>");
                    }
                    else {
                        write(">");
                    }
                }
                function emitJsxClosingElement(node) {
                    write("</");
                    emit(node.tagName);
                    write(">");
                }
                function emitJsxElement(node) {
                    emitJsxOpeningOrSelfClosingElement(node.openingElement);
                    for (var i = 0, n = node.children.length; i < n; i++) {
                        emit(node.children[i]);
                    }
                    emitJsxClosingElement(node.closingElement);
                }
                if (node.kind === 241 /* JsxElement */) {
                    emitJsxElement(node);
                }
                else {
                    ts.Debug.assert(node.kind === 242 /* JsxSelfClosingElement */);
                    emitJsxOpeningOrSelfClosingElement(node);
                }
            }
            // This function specifically handles numeric/string literals for enum and accessor 'identifiers'.
            // In a sense, it does not actually emit identifiers as much as it declares a name for a specific property.
            // For example, this is utilized when feeding in a result to Object.defineProperty.
            function emitExpressionForPropertyName(node) {
                ts.Debug.assert(node.kind !== 169 /* BindingElement */);
                if (node.kind === 9 /* StringLiteral */) {
                    emitLiteral(node);
                }
                else if (node.kind === 140 /* ComputedPropertyName */) {
                    // if this is a decorated computed property, we will need to capture the result
                    // of the property expression so that we can apply decorators later. This is to ensure
                    // we don't introduce unintended side effects:
                    //
                    //   class C {
                    //     [_a = x]() { }
                    //   }
                    //
                    // The emit for the decorated computed property decorator is:
                    //
                    //   __decorate([dec], C.prototype, _a, Object.getOwnPropertyDescriptor(C.prototype, _a));
                    //
                    if (ts.nodeIsDecorated(node.parent)) {
                        if (!computedPropertyNamesToGeneratedNames) {
                            computedPropertyNamesToGeneratedNames = [];
                        }
                        var generatedName = computedPropertyNamesToGeneratedNames[ts.getNodeId(node)];
                        if (generatedName) {
                            // we have already generated a variable for this node, write that value instead.
                            write(generatedName);
                            return;
                        }
                        generatedName = createAndRecordTempVariable(0 /* Auto */).text;
                        computedPropertyNamesToGeneratedNames[ts.getNodeId(node)] = generatedName;
                        write(generatedName);
                        write(" = ");
                    }
                    emit(node.expression);
                }
                else {
                    write('"');
                    if (node.kind === 8 /* NumericLiteral */) {
                        write(node.text);
                    }
                    else {
                        writeTextOfNode(currentText, node);
                    }
                    write('"');
                }
            }
            function isExpressionIdentifier(node) {
                var parent = node.parent;
                switch (parent.kind) {
                    case 170 /* ArrayLiteralExpression */:
                    case 195 /* AsExpression */:
                    case 184 /* AwaitExpression */:
                    case 187 /* BinaryExpression */:
                    case 174 /* CallExpression */:
                    case 249 /* CaseClause */:
                    case 140 /* ComputedPropertyName */:
                    case 188 /* ConditionalExpression */:
                    case 143 /* Decorator */:
                    case 181 /* DeleteExpression */:
                    case 204 /* DoStatement */:
                    case 173 /* ElementAccessExpression */:
                    case 235 /* ExportAssignment */:
                    case 202 /* ExpressionStatement */:
                    case 194 /* ExpressionWithTypeArguments */:
                    case 206 /* ForStatement */:
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                    case 203 /* IfStatement */:
                    case 245 /* JsxClosingElement */:
                    case 242 /* JsxSelfClosingElement */:
                    case 243 /* JsxOpeningElement */:
                    case 247 /* JsxSpreadAttribute */:
                    case 248 /* JsxExpression */:
                    case 175 /* NewExpression */:
                    case 196 /* NonNullExpression */:
                    case 178 /* ParenthesizedExpression */:
                    case 186 /* PostfixUnaryExpression */:
                    case 185 /* PrefixUnaryExpression */:
                    case 211 /* ReturnStatement */:
                    case 254 /* ShorthandPropertyAssignment */:
                    case 191 /* SpreadElementExpression */:
                    case 213 /* SwitchStatement */:
                    case 176 /* TaggedTemplateExpression */:
                    case 197 /* TemplateSpan */:
                    case 215 /* ThrowStatement */:
                    case 177 /* TypeAssertionExpression */:
                    case 182 /* TypeOfExpression */:
                    case 183 /* VoidExpression */:
                    case 205 /* WhileStatement */:
                    case 212 /* WithStatement */:
                    case 190 /* YieldExpression */:
                        return true;
                    case 169 /* BindingElement */:
                    case 255 /* EnumMember */:
                    case 142 /* Parameter */:
                    case 253 /* PropertyAssignment */:
                    case 145 /* PropertyDeclaration */:
                    case 218 /* VariableDeclaration */:
                        return parent.initializer === node;
                    case 172 /* PropertyAccessExpression */:
                        return parent.expression === node;
                    case 180 /* ArrowFunction */:
                    case 179 /* FunctionExpression */:
                        return parent.body === node;
                    case 229 /* ImportEqualsDeclaration */:
                        return parent.moduleReference === node;
                    case 139 /* QualifiedName */:
                        return parent.left === node;
                }
                return false;
            }
            function emitExpressionIdentifier(node) {
                var container = resolver.getReferencedExportContainer(node);
                if (container) {
                    if (container.kind === 256 /* SourceFile */) {
                        // Identifier references module export
                        if (modulekind !== ts.ModuleKind.ES6 && modulekind !== ts.ModuleKind.System) {
                            write("exports.");
                        }
                    }
                    else {
                        // Identifier references namespace export
                        write(getGeneratedNameForNode(container));
                        write(".");
                    }
                }
                else {
                    if (modulekind !== ts.ModuleKind.ES6) {
                        var declaration = resolver.getReferencedImportDeclaration(node);
                        if (declaration) {
                            if (declaration.kind === 231 /* ImportClause */) {
                                // Identifier references default import
                                write(getGeneratedNameForNode(declaration.parent));
                                write(languageVersion === 0 /* ES3 */ ? '["default"]' : ".default");
                                return;
                            }
                            else if (declaration.kind === 234 /* ImportSpecifier */) {
                                // Identifier references named import
                                write(getGeneratedNameForNode(declaration.parent.parent.parent));
                                var name_26 = declaration.propertyName || declaration.name;
                                var identifier = ts.getTextOfNodeFromSourceText(currentText, name_26);
                                if (languageVersion === 0 /* ES3 */ && identifier === "default") {
                                    write('["default"]');
                                }
                                else {
                                    write(".");
                                    write(identifier);
                                }
                                return;
                            }
                        }
                    }
                    if (languageVersion < 2 /* ES6 */) {
                        var declaration = resolver.getReferencedDeclarationWithCollidingName(node);
                        if (declaration) {
                            write(getGeneratedNameForNode(declaration.name));
                            return;
                        }
                    }
                    else if (resolver.getNodeCheckFlags(node) & 1048576 /* BodyScopedClassBinding */) {
                        // 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.
                        var declaration = resolver.getReferencedValueDeclaration(node);
                        if (declaration) {
                            var classAlias = decoratedClassAliases[ts.getNodeId(declaration)];
                            if (classAlias !== undefined) {
                                write(classAlias);
                                return;
                            }
                        }
                    }
                }
                if (ts.nodeIsSynthesized(node)) {
                    write(node.text);
                }
                else {
                    writeTextOfNode(currentText, node);
                }
            }
            function isNameOfNestedBlockScopedRedeclarationOrCapturedBinding(node) {
                if (languageVersion < 2 /* ES6 */) {
                    var parent_13 = node.parent;
                    switch (parent_13.kind) {
                        case 169 /* BindingElement */:
                        case 221 /* ClassDeclaration */:
                        case 224 /* EnumDeclaration */:
                        case 218 /* VariableDeclaration */:
                            return parent_13.name === node && resolver.isDeclarationWithCollidingName(parent_13);
                    }
                }
                return false;
            }
            function getClassExpressionInPropertyAccessInStaticPropertyDeclaration(node) {
                if (languageVersion >= 2 /* ES6 */) {
                    var parent_14 = node.parent;
                    if (parent_14.kind === 172 /* PropertyAccessExpression */ && parent_14.expression === node) {
                        parent_14 = parent_14.parent;
                        while (parent_14 && parent_14.kind !== 145 /* PropertyDeclaration */) {
                            parent_14 = parent_14.parent;
                        }
                        return parent_14 && parent_14.kind === 145 /* PropertyDeclaration */ && (parent_14.flags & 32 /* Static */) !== 0 &&
                            parent_14.parent.kind === 192 /* ClassExpression */ ? parent_14.parent : undefined;
                    }
                }
                return undefined;
            }
            function emitIdentifier(node) {
                if (convertedLoopState) {
                    if (node.text == "arguments" && resolver.isArgumentsLocalBinding(node)) {
                        // in converted loop body arguments cannot be used directly.
                        var name_27 = convertedLoopState.argumentsName || (convertedLoopState.argumentsName = makeUniqueName("arguments"));
                        write(name_27);
                        return;
                    }
                }
                if (!node.parent) {
                    write(node.text);
                }
                else if (isExpressionIdentifier(node)) {
                    var classExpression = getClassExpressionInPropertyAccessInStaticPropertyDeclaration(node);
                    if (classExpression) {
                        var declaration = resolver.getReferencedValueDeclaration(node);
                        if (declaration === classExpression) {
                            write(getGeneratedNameForNode(declaration.name));
                            return;
                        }
                    }
                    emitExpressionIdentifier(node);
                }
                else if (isNameOfNestedBlockScopedRedeclarationOrCapturedBinding(node)) {
                    write(getGeneratedNameForNode(node));
                }
                else if (ts.nodeIsSynthesized(node)) {
                    write(node.text);
                }
                else {
                    writeTextOfNode(currentText, node);
                }
            }
            function emitThis(node) {
                if (resolver.getNodeCheckFlags(node) & 2 /* LexicalThis */) {
                    write("_this");
                }
                else if (convertedLoopState) {
                    write(convertedLoopState.thisName || (convertedLoopState.thisName = makeUniqueName("this")));
                }
                else {
                    write("this");
                }
            }
            function emitSuper(node) {
                if (languageVersion >= 2 /* ES6 */) {
                    write("super");
                }
                else {
                    var flags = resolver.getNodeCheckFlags(node);
                    if (flags & 256 /* SuperInstance */) {
                        write("_super.prototype");
                    }
                    else {
                        write("_super");
                    }
                }
            }
            function emitObjectBindingPattern(node) {
                write("{ ");
                var elements = node.elements;
                emitList(elements, 0, elements.length, /*multiLine*/ false, /*trailingComma*/ elements.hasTrailingComma);
                write(" }");
            }
            function emitArrayBindingPattern(node) {
                write("[");
                var elements = node.elements;
                emitList(elements, 0, elements.length, /*multiLine*/ false, /*trailingComma*/ elements.hasTrailingComma);
                write("]");
            }
            function emitBindingElement(node) {
                if (node.propertyName) {
                    emit(node.propertyName);
                    write(": ");
                }
                if (node.dotDotDotToken) {
                    write("...");
                }
                if (ts.isBindingPattern(node.name)) {
                    emit(node.name);
                }
                else {
                    emitModuleMemberName(node);
                }
                emitOptional(" = ", node.initializer);
            }
            function emitSpreadElementExpression(node) {
                write("...");
                emit(node.expression);
            }
            function emitYieldExpression(node) {
                write(ts.tokenToString(114 /* YieldKeyword */));
                if (node.asteriskToken) {
                    write("*");
                }
                if (node.expression) {
                    write(" ");
                    emit(node.expression);
                }
            }
            function emitAwaitExpression(node) {
                var needsParenthesis = needsParenthesisForAwaitExpressionAsYield(node);
                if (needsParenthesis) {
                    write("(");
                }
                write(ts.tokenToString(114 /* YieldKeyword */));
                write(" ");
                emit(node.expression);
                if (needsParenthesis) {
                    write(")");
                }
            }
            function needsParenthesisForAwaitExpressionAsYield(node) {
                if (node.parent.kind === 187 /* BinaryExpression */ && !ts.isAssignmentOperator(node.parent.operatorToken.kind)) {
                    return true;
                }
                else if (node.parent.kind === 188 /* ConditionalExpression */ && node.parent.condition === node) {
                    return true;
                }
                return false;
            }
            function needsParenthesisForPropertyAccessOrInvocation(node) {
                switch (node.kind) {
                    case 69 /* Identifier */:
                    case 170 /* ArrayLiteralExpression */:
                    case 172 /* PropertyAccessExpression */:
                    case 173 /* ElementAccessExpression */:
                    case 174 /* CallExpression */:
                    case 178 /* ParenthesizedExpression */:
                        // This list is not exhaustive and only includes those cases that are relevant
                        // to the check in emitArrayLiteral. More cases can be added as needed.
                        return false;
                }
                return true;
            }
            function emitListWithSpread(elements, needsUniqueCopy, multiLine, trailingComma, useConcat) {
                var pos = 0;
                var group = 0;
                var length = elements.length;
                while (pos < length) {
                    // Emit using the pattern <group0>.concat(<group1>, <group2>, ...)
                    if (group === 1 && useConcat) {
                        write(".concat(");
                    }
                    else if (group > 0) {
                        write(", ");
                    }
                    var e = elements[pos];
                    if (e.kind === 191 /* SpreadElementExpression */) {
                        e = e.expression;
                        emitParenthesizedIf(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccessOrInvocation(e));
                        pos++;
                        if (pos === length && group === 0 && needsUniqueCopy && e.kind !== 170 /* ArrayLiteralExpression */) {
                            write(".slice()");
                        }
                    }
                    else {
                        var i = pos;
                        while (i < length && elements[i].kind !== 191 /* SpreadElementExpression */) {
                            i++;
                        }
                        write("[");
                        if (multiLine) {
                            increaseIndent();
                        }
                        emitList(elements, pos, i - pos, multiLine, trailingComma && i === length);
                        if (multiLine) {
                            decreaseIndent();
                        }
                        write("]");
                        pos = i;
                    }
                    group++;
                }
                if (group > 1) {
                    if (useConcat) {
                        write(")");
                    }
                }
            }
            function isSpreadElementExpression(node) {
                return node.kind === 191 /* SpreadElementExpression */;
            }
            function emitArrayLiteral(node) {
                var elements = node.elements;
                if (elements.length === 0) {
                    write("[]");
                }
                else if (languageVersion >= 2 /* ES6 */ || !ts.forEach(elements, isSpreadElementExpression)) {
                    write("[");
                    emitLinePreservingList(node, node.elements, elements.hasTrailingComma, /*spacesBetweenBraces*/ false);
                    write("]");
                }
                else {
                    emitListWithSpread(elements, /*needsUniqueCopy*/ true, /*multiLine*/ node.multiLine, 
                    /*trailingComma*/ elements.hasTrailingComma, /*useConcat*/ true);
                }
            }
            function emitObjectLiteralBody(node, numElements) {
                if (numElements === 0) {
                    write("{}");
                    return;
                }
                write("{");
                if (numElements > 0) {
                    var properties = node.properties;
                    // If we are not doing a downlevel transformation for object literals,
                    // then try to preserve the original shape of the object literal.
                    // Otherwise just try to preserve the formatting.
                    if (numElements === properties.length) {
                        emitLinePreservingList(node, properties, /*allowTrailingComma*/ languageVersion >= 1 /* ES5 */, /*spacesBetweenBraces*/ true);
                    }
                    else {
                        var multiLine = node.multiLine;
                        if (!multiLine) {
                            write(" ");
                        }
                        else {
                            increaseIndent();
                        }
                        emitList(properties, 0, numElements, /*multiLine*/ multiLine, /*trailingComma*/ false);
                        if (!multiLine) {
                            write(" ");
                        }
                        else {
                            decreaseIndent();
                        }
                    }
                }
                write("}");
            }
            function emitDownlevelObjectLiteralWithComputedProperties(node, firstComputedPropertyIndex) {
                var multiLine = node.multiLine;
                var properties = node.properties;
                write("(");
                if (multiLine) {
                    increaseIndent();
                }
                // For computed properties, we need to create a unique handle to the object
                // literal so we can modify it without risking internal assignments tainting the object.
                var tempVar = createAndRecordTempVariable(0 /* Auto */);
                // Write out the first non-computed properties
                // (or all properties if none of them are computed),
                // then emit the rest through indexing on the temp variable.
                emit(tempVar);
                write(" = ");
                emitObjectLiteralBody(node, firstComputedPropertyIndex);
                for (var i = firstComputedPropertyIndex, n = properties.length; i < n; i++) {
                    writeComma();
                    var property = properties[i];
                    emitStart(property);
                    if (property.kind === 149 /* GetAccessor */ || property.kind === 150 /* SetAccessor */) {
                        // TODO (drosen): Reconcile with 'emitMemberFunctions'.
                        var accessors = ts.getAllAccessorDeclarations(node.properties, property);
                        if (property !== accessors.firstAccessor) {
                            continue;
                        }
                        write("Object.defineProperty(");
                        emit(tempVar);
                        write(", ");
                        emitStart(property.name);
                        emitExpressionForPropertyName(property.name);
                        emitEnd(property.name);
                        write(", {");
                        increaseIndent();
                        if (accessors.getAccessor) {
                            writeLine();
                            emitLeadingComments(accessors.getAccessor);
                            write("get: ");
                            emitStart(accessors.getAccessor);
                            write("function ");
                            emitSignatureAndBody(accessors.getAccessor);
                            emitEnd(accessors.getAccessor);
                            emitTrailingComments(accessors.getAccessor);
                            write(",");
                        }
                        if (accessors.setAccessor) {
                            writeLine();
                            emitLeadingComments(accessors.setAccessor);
                            write("set: ");
                            emitStart(accessors.setAccessor);
                            write("function ");
                            emitSignatureAndBody(accessors.setAccessor);
                            emitEnd(accessors.setAccessor);
                            emitTrailingComments(accessors.setAccessor);
                            write(",");
                        }
                        writeLine();
                        write("enumerable: true,");
                        writeLine();
                        write("configurable: true");
                        decreaseIndent();
                        writeLine();
                        write("})");
                        emitEnd(property);
                    }
                    else {
                        emitLeadingComments(property);
                        emitStart(property.name);
                        emit(tempVar);
                        emitMemberAccessForPropertyName(property.name);
                        emitEnd(property.name);
                        write(" = ");
                        if (property.kind === 253 /* PropertyAssignment */) {
                            emit(property.initializer);
                        }
                        else if (property.kind === 254 /* ShorthandPropertyAssignment */) {
                            emitExpressionIdentifier(property.name);
                        }
                        else if (property.kind === 147 /* MethodDeclaration */) {
                            emitFunctionDeclaration(property);
                        }
                        else {
                            ts.Debug.fail("ObjectLiteralElement type not accounted for: " + property.kind);
                        }
                    }
                    emitEnd(property);
                }
                writeComma();
                emit(tempVar);
                if (multiLine) {
                    decreaseIndent();
                    writeLine();
                }
                write(")");
                function writeComma() {
                    if (multiLine) {
                        write(",");
                        writeLine();
                    }
                    else {
                        write(", ");
                    }
                }
            }
            function emitObjectLiteral(node) {
                var properties = node.properties;
                if (languageVersion < 2 /* ES6 */) {
                    var numProperties = properties.length;
                    // Find the first computed property.
                    // Everything until that point can be emitted as part of the initial object literal.
                    var numInitialNonComputedProperties = numProperties;
                    for (var i = 0, n = properties.length; i < n; i++) {
                        if (properties[i].name.kind === 140 /* ComputedPropertyName */) {
                            numInitialNonComputedProperties = i;
                            break;
                        }
                    }
                    var hasComputedProperty = numInitialNonComputedProperties !== properties.length;
                    if (hasComputedProperty) {
                        emitDownlevelObjectLiteralWithComputedProperties(node, numInitialNonComputedProperties);
                        return;
                    }
                }
                // Ordinary case: either the object has no computed properties
                // or we're compiling with an ES6+ target.
                emitObjectLiteralBody(node, properties.length);
            }
            function createBinaryExpression(left, operator, right, startsOnNewLine) {
                var result = ts.createSynthesizedNode(187 /* BinaryExpression */, startsOnNewLine);
                result.operatorToken = ts.createSynthesizedNode(operator);
                result.left = left;
                result.right = right;
                return result;
            }
            function createPropertyAccessExpression(expression, name) {
                var result = ts.createSynthesizedNode(172 /* PropertyAccessExpression */);
                result.expression = parenthesizeForAccess(expression);
                result.name = name;
                return result;
            }
            function createElementAccessExpression(expression, argumentExpression) {
                var result = ts.createSynthesizedNode(173 /* ElementAccessExpression */);
                result.expression = parenthesizeForAccess(expression);
                result.argumentExpression = argumentExpression;
                return result;
            }
            function parenthesizeForAccess(expr) {
                // When diagnosing whether the expression needs parentheses, the decision should be based
                // on the innermost expression in a chain of nested type assertions.
                while (expr.kind === 177 /* TypeAssertionExpression */ ||
                    expr.kind === 195 /* AsExpression */ ||
                    expr.kind === 196 /* NonNullExpression */) {
                    expr = expr.expression;
                }
                // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
                // to parenthesize the expression before a dot. The known exceptions are:
                //
                //    NewExpression:
                //       new C.x        -> not the same as (new C).x
                //    NumberLiteral
                //       1.x            -> not the same as (1).x
                //
                if (ts.isLeftHandSideExpression(expr) &&
                    expr.kind !== 175 /* NewExpression */ &&
                    expr.kind !== 8 /* NumericLiteral */) {
                    return expr;
                }
                var node = ts.createSynthesizedNode(178 /* ParenthesizedExpression */);
                node.expression = expr;
                return node;
            }
            function emitComputedPropertyName(node) {
                write("[");
                emitExpressionForPropertyName(node);
                write("]");
            }
            function emitMethod(node) {
                if (languageVersion >= 2 /* ES6 */ && node.asteriskToken) {
                    write("*");
                }
                emit(node.name);
                if (languageVersion < 2 /* ES6 */) {
                    write(": function ");
                }
                emitSignatureAndBody(node);
            }
            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.
                emitTrailingCommentsOfPosition(node.initializer.pos);
                emit(node.initializer);
            }
            // Return true if identifier resolves to an exported member of a namespace
            function isExportReference(node) {
                var container = resolver.getReferencedExportContainer(node);
                return !!container;
            }
            // Return true if identifier resolves to an imported identifier
            function isImportedReference(node) {
                var declaration = resolver.getReferencedImportDeclaration(node);
                return declaration && (declaration.kind === 231 /* ImportClause */ || declaration.kind === 234 /* ImportSpecifier */);
            }
            function emitShorthandPropertyAssignment(node) {
                // The name property of a short-hand property assignment is considered an expression position, so here
                // we manually emit the identifier to avoid rewriting.
                writeTextOfNode(currentText, node.name);
                // If emitting pre-ES6 code, or if the name requires rewriting when resolved as an expression identifier,
                // we emit a normal property assignment. For example:
                //   module m {
                //       export let y;
                //   }
                //   module m {
                //       let obj = { y };
                //   }
                // Here we need to emit obj = { y : m.y } regardless of the output target.
                // The same rules apply for imported identifiers when targeting module formats with indirect access to
                // the imported identifiers. For example, when targeting CommonJS:
                //
                //   import {foo} from './foo';
                //   export const baz = { foo };
                //
                // Must be transformed into:
                //
                //   const foo_1 = require('./foo');
                //   exports.baz = { foo: foo_1.foo };
                //
                if (languageVersion < 2 /* ES6 */ || (modulekind !== ts.ModuleKind.ES6 && isImportedReference(node.name)) || isExportReference(node.name)) {
                    // Emit identifier as an identifier
                    write(": ");
                    emitExpressionIdentifier(node.name);
                }
                if (languageVersion >= 2 /* ES6 */ && node.objectAssignmentInitializer) {
                    write(" = ");
                    emit(node.objectAssignmentInitializer);
                }
            }
            function tryEmitConstantValue(node) {
                var constantValue = tryGetConstEnumValue(node);
                if (constantValue !== undefined) {
                    write(constantValue.toString());
                    if (!compilerOptions.removeComments) {
                        var propertyName = node.kind === 172 /* PropertyAccessExpression */ ? ts.declarationNameToString(node.name) : ts.getTextOfNode(node.argumentExpression);
                        write(" /* " + propertyName + " */");
                    }
                    return true;
                }
                return false;
            }
            function tryGetConstEnumValue(node) {
                if (compilerOptions.isolatedModules) {
                    return undefined;
                }
                return node.kind === 172 /* PropertyAccessExpression */ || node.kind === 173 /* ElementAccessExpression */
                    ? resolver.getConstantValue(node)
                    : undefined;
            }
            // Returns 'true' if the code was actually indented, false otherwise.
            // If the code is not indented, an optional valueToWriteWhenNotIndenting will be
            // emitted instead.
            function indentIfOnDifferentLines(parent, node1, node2, valueToWriteWhenNotIndenting) {
                var realNodesAreOnDifferentLines = !ts.nodeIsSynthesized(parent) && !nodeEndIsOnSameLineAsNodeStart(node1, node2);
                // Always use a newline for synthesized code if the synthesizer desires it.
                var synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine(node2);
                if (realNodesAreOnDifferentLines || synthesizedNodeIsOnDifferentLine) {
                    increaseIndent();
                    writeLine();
                    return true;
                }
                else {
                    if (valueToWriteWhenNotIndenting) {
                        write(valueToWriteWhenNotIndenting);
                    }
                    return false;
                }
            }
            function emitPropertyAccess(node) {
                if (tryEmitConstantValue(node)) {
                    return;
                }
                if (languageVersion === 2 /* ES6 */ &&
                    node.expression.kind === 95 /* SuperKeyword */ &&
                    isInAsyncMethodWithSuperInES6(node)) {
                    var name_28 = ts.createSynthesizedNode(9 /* StringLiteral */);
                    name_28.text = node.name.text;
                    emitSuperAccessInAsyncMethod(node.expression, name_28);
                    return;
                }
                emit(node.expression);
                var dotRangeStart = ts.nodeIsSynthesized(node.expression) ? -1 : node.expression.end;
                var dotRangeEnd = ts.nodeIsSynthesized(node.expression) ? -1 : ts.skipTrivia(currentText, node.expression.end) + 1;
                var dotToken = { pos: dotRangeStart, end: dotRangeEnd };
                var indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, dotToken);
                // 1 .toString is a valid property access, emit a space after the literal
                // Also emit a space if expression is a integer const enum value - it will appear in generated code as numeric literal
                var shouldEmitSpace = false;
                if (!indentedBeforeDot) {
                    if (node.expression.kind === 8 /* NumericLiteral */) {
                        // check if numeric literal was originally written with a dot
                        var text = ts.getTextOfNodeFromSourceText(currentText, node.expression);
                        shouldEmitSpace = text.indexOf(ts.tokenToString(21 /* DotToken */)) < 0;
                    }
                    else {
                        // check if constant enum value is integer
                        var constantValue = tryGetConstEnumValue(node.expression);
                        // isFinite handles cases when constantValue is undefined
                        shouldEmitSpace = isFinite(constantValue) && Math.floor(constantValue) === constantValue;
                    }
                }
                if (shouldEmitSpace) {
                    write(" .");
                }
                else {
                    write(".");
                }
                var indentedAfterDot = indentIfOnDifferentLines(node, dotToken, node.name);
                emit(node.name);
                decreaseIndentIf(indentedBeforeDot, indentedAfterDot);
            }
            function emitQualifiedName(node) {
                emit(node.left);
                write(".");
                emit(node.right);
            }
            function emitQualifiedNameAsExpression(node, useFallback) {
                if (node.left.kind === 69 /* Identifier */) {
                    emitEntityNameAsExpression(node.left, useFallback);
                }
                else if (useFallback) {
                    var temp = createAndRecordTempVariable(0 /* Auto */);
                    write("(");
                    emitNodeWithoutSourceMap(temp);
                    write(" = ");
                    emitEntityNameAsExpression(node.left, /*useFallback*/ true);
                    write(") && ");
                    emitNodeWithoutSourceMap(temp);
                }
                else {
                    emitEntityNameAsExpression(node.left, /*useFallback*/ false);
                }
                write(".");
                emit(node.right);
            }
            function emitEntityNameAsExpression(node, useFallback) {
                switch (node.kind) {
                    case 69 /* Identifier */:
                        if (useFallback) {
                            write("typeof ");
                            emitExpressionIdentifier(node);
                            write(" !== 'undefined' && ");
                        }
                        emitExpressionIdentifier(node);
                        break;
                    case 139 /* QualifiedName */:
                        emitQualifiedNameAsExpression(node, useFallback);
                        break;
                    default:
                        emitNodeWithoutSourceMap(node);
                        break;
                }
            }
            function emitIndexedAccess(node) {
                if (tryEmitConstantValue(node)) {
                    return;
                }
                if (languageVersion === 2 /* ES6 */ &&
                    node.expression.kind === 95 /* SuperKeyword */ &&
                    isInAsyncMethodWithSuperInES6(node)) {
                    emitSuperAccessInAsyncMethod(node.expression, node.argumentExpression);
                    return;
                }
                emit(node.expression);
                write("[");
                emit(node.argumentExpression);
                write("]");
            }
            function hasSpreadElement(elements) {
                return ts.forEach(elements, function (e) { return e.kind === 191 /* SpreadElementExpression */; });
            }
            function skipParentheses(node) {
                while (node.kind === 178 /* ParenthesizedExpression */ ||
                    node.kind === 177 /* TypeAssertionExpression */ ||
                    node.kind === 195 /* AsExpression */ ||
                    node.kind === 196 /* NonNullExpression */) {
                    node = node.expression;
                }
                return node;
            }
            function emitCallTarget(node) {
                if (node.kind === 69 /* Identifier */ || node.kind === 97 /* ThisKeyword */ || node.kind === 95 /* SuperKeyword */) {
                    emit(node);
                    return node;
                }
                var temp = createAndRecordTempVariable(0 /* Auto */);
                write("(");
                emit(temp);
                write(" = ");
                emit(node);
                write(")");
                return temp;
            }
            function emitCallWithSpread(node) {
                var target;
                var expr = skipParentheses(node.expression);
                if (expr.kind === 172 /* PropertyAccessExpression */) {
                    // Target will be emitted as "this" argument
                    target = emitCallTarget(expr.expression);
                    write(".");
                    emit(expr.name);
                }
                else if (expr.kind === 173 /* ElementAccessExpression */) {
                    // Target will be emitted as "this" argument
                    target = emitCallTarget(expr.expression);
                    write("[");
                    emit(expr.argumentExpression);
                    write("]");
                }
                else if (expr.kind === 95 /* SuperKeyword */) {
                    target = expr;
                    write("_super");
                }
                else {
                    emit(node.expression);
                }
                write(".apply(");
                if (target) {
                    if (target.kind === 95 /* SuperKeyword */) {
                        // Calls of form super(...) and super.foo(...)
                        emitThis(target);
                    }
                    else {
                        // Calls of form obj.foo(...)
                        emit(target);
                    }
                }
                else {
                    // Calls of form foo(...)
                    write("void 0");
                }
                write(", ");
                emitListWithSpread(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false, /*useConcat*/ true);
                write(")");
            }
            function isInAsyncMethodWithSuperInES6(node) {
                if (languageVersion === 2 /* ES6 */) {
                    var container = ts.getSuperContainer(node, /*includeFunctions*/ false);
                    if (container && resolver.getNodeCheckFlags(container) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */)) {
                        return true;
                    }
                }
                return false;
            }
            function emitSuperAccessInAsyncMethod(superNode, argumentExpression) {
                var container = ts.getSuperContainer(superNode, /*includeFunctions*/ false);
                var isSuperBinding = resolver.getNodeCheckFlags(container) & 4096 /* AsyncMethodWithSuperBinding */;
                write("_super(");
                emit(argumentExpression);
                write(isSuperBinding ? ").value" : ")");
            }
            function emitCallExpression(node) {
                if (languageVersion < 2 /* ES6 */ && hasSpreadElement(node.arguments)) {
                    emitCallWithSpread(node);
                    return;
                }
                var expression = node.expression;
                var superCall = false;
                var isAsyncMethodWithSuper = false;
                if (expression.kind === 95 /* SuperKeyword */) {
                    emitSuper(expression);
                    superCall = true;
                }
                else {
                    superCall = ts.isSuperPropertyOrElementAccess(expression);
                    isAsyncMethodWithSuper = superCall && isInAsyncMethodWithSuperInES6(node);
                    emit(expression);
                }
                if (superCall && (languageVersion < 2 /* ES6 */ || isAsyncMethodWithSuper)) {
                    write(".call(");
                    emitThis(expression);
                    if (node.arguments.length) {
                        write(", ");
                        emitCommaList(node.arguments);
                    }
                    write(")");
                }
                else {
                    write("(");
                    emitCommaList(node.arguments);
                    write(")");
                }
            }
            function emitNewExpression(node) {
                write("new ");
                // Spread operator logic is supported in new expressions in ES5 using a combination
                // of Function.prototype.bind() and Function.prototype.apply().
                //
                //     Example:
                //
                //         var args = [1, 2, 3, 4, 5];
                //         new Array(...args);
                //
                //     is compiled into the following ES5:
                //
                //         var args = [1, 2, 3, 4, 5];
                //         new (Array.bind.apply(Array, [void 0].concat(args)));
                //
                // The 'thisArg' to 'bind' is ignored when invoking the result of 'bind' with 'new',
                // Thus, we set it to undefined ('void 0').
                if (languageVersion === 1 /* ES5 */ &&
                    node.arguments &&
                    hasSpreadElement(node.arguments)) {
                    write("(");
                    var target = emitCallTarget(node.expression);
                    write(".bind.apply(");
                    emit(target);
                    write(", [void 0].concat(");
                    emitListWithSpread(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false, /*useConcat*/ false);
                    write(")))");
                    write("()");
                }
                else {
                    emit(node.expression);
                    if (node.arguments) {
                        write("(");
                        emitCommaList(node.arguments);
                        write(")");
                    }
                }
            }
            function emitTaggedTemplateExpression(node) {
                if (languageVersion >= 2 /* ES6 */) {
                    emit(node.tag);
                    write(" ");
                    emit(node.template);
                }
                else {
                    emitDownlevelTaggedTemplate(node);
                }
            }
            function emitParenExpression(node) {
                // If 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 (!ts.nodeIsSynthesized(node) && node.parent.kind !== 180 /* ArrowFunction */) {
                    if (node.expression.kind === 177 /* TypeAssertionExpression */ ||
                        node.expression.kind === 195 /* AsExpression */ ||
                        node.expression.kind === 196 /* NonNullExpression */) {
                        var operand = node.expression.expression;
                        // Make sure we consider all nested cast expressions, e.g.:
                        // (<any><number><any>-A).x;
                        while (operand.kind === 177 /* TypeAssertionExpression */ ||
                            operand.kind === 195 /* AsExpression */ ||
                            operand.kind === 196 /* NonNullExpression */) {
                            operand = operand.expression;
                        }
                        // We have an expression of the form: (<Type>SubExpr)
                        // Emitting this as (SubExpr) is really not desirable. We would like to emit the subexpr as is.
                        // Omitting the parentheses, however, could cause change in the semantics of the generated
                        // code if the casted expression has a lower precedence than the rest of the expression, e.g.:
                        //      (<any>new A).foo should be emitted as (new A).foo and not new A.foo
                        //      (<any>typeof A).toString() should be emitted as (typeof A).toString() and not typeof A.toString()
                        //      new (<any>A()) should be emitted as new (A()) and not new A()
                        //      (<any>function foo() { })() should be emitted as an IIF (function foo(){})() and not declaration function foo(){} ()
                        if (operand.kind !== 185 /* PrefixUnaryExpression */ &&
                            operand.kind !== 183 /* VoidExpression */ &&
                            operand.kind !== 182 /* TypeOfExpression */ &&
                            operand.kind !== 181 /* DeleteExpression */ &&
                            operand.kind !== 186 /* PostfixUnaryExpression */ &&
                            operand.kind !== 175 /* NewExpression */ &&
                            !(operand.kind === 174 /* CallExpression */ && node.parent.kind === 175 /* NewExpression */) &&
                            !(operand.kind === 179 /* FunctionExpression */ && node.parent.kind === 174 /* CallExpression */) &&
                            !(operand.kind === 8 /* NumericLiteral */ && node.parent.kind === 172 /* PropertyAccessExpression */)) {
                            emit(operand);
                            return;
                        }
                    }
                }
                write("(");
                emit(node.expression);
                write(")");
            }
            function emitDeleteExpression(node) {
                write(ts.tokenToString(78 /* DeleteKeyword */));
                write(" ");
                emit(node.expression);
            }
            function emitVoidExpression(node) {
                write(ts.tokenToString(103 /* VoidKeyword */));
                write(" ");
                emit(node.expression);
            }
            function emitTypeOfExpression(node) {
                write(ts.tokenToString(101 /* TypeOfKeyword */));
                write(" ");
                emit(node.expression);
            }
            function isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node) {
                if (!isCurrentFileSystemExternalModule() || node.kind !== 69 /* Identifier */ || ts.nodeIsSynthesized(node)) {
                    return false;
                }
                var isVariableDeclarationOrBindingElement = node.parent && (node.parent.kind === 218 /* VariableDeclaration */ || node.parent.kind === 169 /* BindingElement */);
                var targetDeclaration = isVariableDeclarationOrBindingElement
                    ? node.parent
                    : resolver.getReferencedValueDeclaration(node);
                return isSourceFileLevelDeclarationInSystemJsModule(targetDeclaration, /*isExported*/ true);
            }
            function isNameOfExportedDeclarationInNonES6Module(node) {
                if (modulekind === ts.ModuleKind.System || node.kind !== 69 /* Identifier */ || ts.nodeIsSynthesized(node)) {
                    return false;
                }
                return !exportEquals && exportSpecifiers && ts.hasProperty(exportSpecifiers, node.text);
            }
            function emitPrefixUnaryExpression(node) {
                var isPlusPlusOrMinusMinus = (node.operator === 41 /* PlusPlusToken */
                    || node.operator === 42 /* MinusMinusToken */);
                var externalExportChanged = isPlusPlusOrMinusMinus &&
                    isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
                if (externalExportChanged) {
                    // emit
                    // ++x
                    // as
                    // exports('x', ++x)
                    write(exportFunctionForFile + "(\"");
                    emitNodeWithoutSourceMap(node.operand);
                    write("\", ");
                }
                var internalExportChanged = isPlusPlusOrMinusMinus &&
                    isNameOfExportedDeclarationInNonES6Module(node.operand);
                if (internalExportChanged) {
                    emitAliasEqual(node.operand);
                }
                write(ts.tokenToString(node.operator));
                // In some cases, we need to emit a space between the operator and the operand. One obvious case
                // is when the operator is an identifier, like delete or typeof. We also need to do this for plus
                // and minus expressions in certain cases. Specifically, consider the following two cases (parens
                // are just for clarity of exposition, and not part of the source code):
                //
                //  (+(+1))
                //  (+(++1))
                //
                // We need to emit a space in both cases. In the first case, the absence of a space will make
                // the resulting expression a prefix increment operation. And in the second, it will make the resulting
                // expression a prefix increment whose operand is a plus expression - (++(+x))
                // The same is true of minus of course.
                if (node.operand.kind === 185 /* PrefixUnaryExpression */) {
                    var operand = node.operand;
                    if (node.operator === 35 /* PlusToken */ && (operand.operator === 35 /* PlusToken */ || operand.operator === 41 /* PlusPlusToken */)) {
                        write(" ");
                    }
                    else if (node.operator === 36 /* MinusToken */ && (operand.operator === 36 /* MinusToken */ || operand.operator === 42 /* MinusMinusToken */)) {
                        write(" ");
                    }
                }
                emit(node.operand);
                if (externalExportChanged) {
                    write(")");
                }
            }
            function emitPostfixUnaryExpression(node) {
                var externalExportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
                var internalExportChanged = isNameOfExportedDeclarationInNonES6Module(node.operand);
                if (externalExportChanged) {
                    // export function returns the value that was passes as the second argument
                    // however for postfix unary expressions result value should be the value before modification.
                    // emit 'x++' as '(export('x', ++x) - 1)' and 'x--' as '(export('x', --x) + 1)'
                    write("(" + exportFunctionForFile + "(\"");
                    emitNodeWithoutSourceMap(node.operand);
                    write("\", ");
                    write(ts.tokenToString(node.operator));
                    emit(node.operand);
                    if (node.operator === 41 /* PlusPlusToken */) {
                        write(") - 1)");
                    }
                    else {
                        write(") + 1)");
                    }
                }
                else if (internalExportChanged) {
                    emitAliasEqual(node.operand);
                    emit(node.operand);
                    if (node.operator === 41 /* PlusPlusToken */) {
                        write(" += 1");
                    }
                    else {
                        write(" -= 1");
                    }
                }
                else {
                    emit(node.operand);
                    write(ts.tokenToString(node.operator));
                }
            }
            function shouldHoistDeclarationInSystemJsModule(node) {
                return isSourceFileLevelDeclarationInSystemJsModule(node, /*isExported*/ false);
            }
            /*
             * Checks if given node is a source file level declaration (not nested in module/function).
             * If 'isExported' is true - then declaration must also be exported.
             * This function is used in two cases:
             * - check if node is a exported source file level value to determine
             *   if we should also export the value after its it changed
             * - check if node is a source level declaration to emit it differently,
             *   i.e non-exported variable statement 'var x = 1' is hoisted so
             *   we we emit variable statement 'var' should be dropped.
             */
            function isSourceFileLevelDeclarationInSystemJsModule(node, isExported) {
                if (!node || !isCurrentFileSystemExternalModule()) {
                    return false;
                }
                var current = ts.getRootDeclaration(node).parent;
                while (current) {
                    if (current.kind === 256 /* SourceFile */) {
                        return !isExported || ((ts.getCombinedNodeFlags(node) & 1 /* Export */) !== 0);
                    }
                    else if (ts.isDeclaration(current)) {
                        return false;
                    }
                    else {
                        current = current.parent;
                    }
                }
            }
            /**
             * Emit ES7 exponentiation operator downlevel using Math.pow
             * @param node a binary expression node containing exponentiationOperator (**, **=)
             */
            function emitExponentiationOperator(node) {
                var leftHandSideExpression = node.left;
                if (node.operatorToken.kind === 60 /* AsteriskAsteriskEqualsToken */) {
                    var synthesizedLHS = void 0;
                    var shouldEmitParentheses = false;
                    if (ts.isElementAccessExpression(leftHandSideExpression)) {
                        shouldEmitParentheses = true;
                        write("(");
                        synthesizedLHS = ts.createSynthesizedNode(173 /* ElementAccessExpression */, /*startsOnNewLine*/ false);
                        var identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefineTempVariablesInPlace*/ false, /*shouldEmitCommaBeforeAssignment*/ false);
                        synthesizedLHS.expression = identifier;
                        if (leftHandSideExpression.argumentExpression.kind !== 8 /* NumericLiteral */ &&
                            leftHandSideExpression.argumentExpression.kind !== 9 /* StringLiteral */) {
                            var tempArgumentExpression = createAndRecordTempVariable(268435456 /* _i */);
                            synthesizedLHS.argumentExpression = tempArgumentExpression;
                            emitAssignment(tempArgumentExpression, leftHandSideExpression.argumentExpression, /*shouldEmitCommaBeforeAssignment*/ true, leftHandSideExpression.expression);
                        }
                        else {
                            synthesizedLHS.argumentExpression = leftHandSideExpression.argumentExpression;
                        }
                        write(", ");
                    }
                    else if (ts.isPropertyAccessExpression(leftHandSideExpression)) {
                        shouldEmitParentheses = true;
                        write("(");
                        synthesizedLHS = ts.createSynthesizedNode(172 /* PropertyAccessExpression */, /*startsOnNewLine*/ false);
                        var identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefineTempVariablesInPlace*/ false, /*shouldEmitCommaBeforeAssignment*/ false);
                        synthesizedLHS.expression = identifier;
                        synthesizedLHS.name = leftHandSideExpression.name;
                        write(", ");
                    }
                    emit(synthesizedLHS || leftHandSideExpression);
                    write(" = ");
                    write("Math.pow(");
                    emit(synthesizedLHS || leftHandSideExpression);
                    write(", ");
                    emit(node.right);
                    write(")");
                    if (shouldEmitParentheses) {
                        write(")");
                    }
                }
                else {
                    write("Math.pow(");
                    emit(leftHandSideExpression);
                    write(", ");
                    emit(node.right);
                    write(")");
                }
            }
            function emitAliasEqual(name) {
                for (var _a = 0, _b = exportSpecifiers[name.text]; _a < _b.length; _a++) {
                    var specifier = _b[_a];
                    emitStart(specifier.name);
                    emitContainingModuleName(specifier);
                    if (languageVersion === 0 /* ES3 */ && name.text === "default") {
                        write('["default"]');
                    }
                    else {
                        write(".");
                        emitNodeWithCommentsAndWithoutSourcemap(specifier.name);
                    }
                    emitEnd(specifier.name);
                    write(" = ");
                }
                return true;
            }
            function emitBinaryExpression(node) {
                if (languageVersion < 2 /* ES6 */ && node.operatorToken.kind === 56 /* EqualsToken */ &&
                    (node.left.kind === 171 /* ObjectLiteralExpression */ || node.left.kind === 170 /* ArrayLiteralExpression */)) {
                    emitDestructuring(node, node.parent.kind === 202 /* ExpressionStatement */);
                }
                else {
                    var isAssignment = ts.isAssignmentOperator(node.operatorToken.kind);
                    var externalExportChanged = isAssignment &&
                        isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.left);
                    if (externalExportChanged) {
                        // emit assignment 'x <op> y' as 'exports("x", x <op> y)'
                        write(exportFunctionForFile + "(\"");
                        emitNodeWithoutSourceMap(node.left);
                        write("\", ");
                    }
                    var internalExportChanged = isAssignment &&
                        isNameOfExportedDeclarationInNonES6Module(node.left);
                    if (internalExportChanged) {
                        // export { foo }
                        // emit foo = 2 as exports.foo = foo = 2
                        emitAliasEqual(node.left);
                    }
                    if (node.operatorToken.kind === 38 /* AsteriskAsteriskToken */ || node.operatorToken.kind === 60 /* AsteriskAsteriskEqualsToken */) {
                        // Downleveled emit exponentiation operator using Math.pow
                        emitExponentiationOperator(node);
                    }
                    else {
                        emit(node.left);
                        // Add indentation before emit the operator if the operator is on different line
                        // For example:
                        //      3
                        //      + 2;
                        //   emitted as
                        //      3
                        //          + 2;
                        var indentedBeforeOperator = indentIfOnDifferentLines(node, node.left, node.operatorToken, node.operatorToken.kind !== 24 /* CommaToken */ ? " " : undefined);
                        write(ts.tokenToString(node.operatorToken.kind));
                        var indentedAfterOperator = indentIfOnDifferentLines(node, node.operatorToken, node.right, " ");
                        emit(node.right);
                        decreaseIndentIf(indentedBeforeOperator, indentedAfterOperator);
                    }
                    if (externalExportChanged) {
                        write(")");
                    }
                }
            }
            function synthesizedNodeStartsOnNewLine(node) {
                return ts.nodeIsSynthesized(node) && node.startsOnNewLine;
            }
            function emitConditionalExpression(node) {
                emit(node.condition);
                var indentedBeforeQuestion = indentIfOnDifferentLines(node, node.condition, node.questionToken, " ");
                write("?");
                var indentedAfterQuestion = indentIfOnDifferentLines(node, node.questionToken, node.whenTrue, " ");
                emit(node.whenTrue);
                decreaseIndentIf(indentedBeforeQuestion, indentedAfterQuestion);
                var indentedBeforeColon = indentIfOnDifferentLines(node, node.whenTrue, node.colonToken, " ");
                write(":");
                var indentedAfterColon = indentIfOnDifferentLines(node, node.colonToken, node.whenFalse, " ");
                emit(node.whenFalse);
                decreaseIndentIf(indentedBeforeColon, indentedAfterColon);
            }
            // Helper function to decrease the indent if we previously indented.  Allows multiple
            // previous indent values to be considered at a time.  This also allows caller to just
            // call this once, passing in all their appropriate indent values, instead of needing
            // to call this helper function multiple times.
            function decreaseIndentIf(value1, value2) {
                if (value1) {
                    decreaseIndent();
                }
                if (value2) {
                    decreaseIndent();
                }
            }
            function isSingleLineEmptyBlock(node) {
                if (node && node.kind === 199 /* Block */) {
                    var block = node;
                    return block.statements.length === 0 && nodeEndIsOnSameLineAsNodeStart(block, block);
                }
            }
            function emitBlock(node) {
                if (isSingleLineEmptyBlock(node)) {
                    emitToken(15 /* OpenBraceToken */, node.pos);
                    write(" ");
                    emitToken(16 /* CloseBraceToken */, node.statements.end);
                    return;
                }
                emitToken(15 /* OpenBraceToken */, node.pos);
                increaseIndent();
                if (node.kind === 226 /* ModuleBlock */) {
                    ts.Debug.assert(node.parent.kind === 225 /* ModuleDeclaration */);
                    emitCaptureThisForNodeIfNecessary(node.parent);
                }
                emitLines(node.statements);
                if (node.kind === 226 /* ModuleBlock */) {
                    emitTempDeclarations(/*newLine*/ true);
                }
                decreaseIndent();
                writeLine();
                emitToken(16 /* CloseBraceToken */, node.statements.end);
            }
            function emitEmbeddedStatement(node) {
                if (node.kind === 199 /* Block */) {
                    write(" ");
                    emit(node);
                }
                else {
                    increaseIndent();
                    writeLine();
                    emit(node);
                    decreaseIndent();
                }
            }
            function emitExpressionStatement(node) {
                emitParenthesizedIf(node.expression, /*parenthesized*/ node.expression.kind === 180 /* ArrowFunction */);
                write(";");
            }
            function emitIfStatement(node) {
                var endPos = emitToken(88 /* IfKeyword */, node.pos);
                write(" ");
                endPos = emitToken(17 /* OpenParenToken */, endPos);
                emit(node.expression);
                emitToken(18 /* CloseParenToken */, node.expression.end);
                emitEmbeddedStatement(node.thenStatement);
                if (node.elseStatement) {
                    writeLine();
                    emitToken(80 /* ElseKeyword */, node.thenStatement.end);
                    if (node.elseStatement.kind === 203 /* IfStatement */) {
                        write(" ");
                        emit(node.elseStatement);
                    }
                    else {
                        emitEmbeddedStatement(node.elseStatement);
                    }
                }
            }
            function emitDoStatement(node) {
                emitLoop(node, emitDoStatementWorker);
            }
            function emitDoStatementWorker(node, loop) {
                write("do");
                if (loop) {
                    emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
                }
                else {
                    emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
                }
                if (node.statement.kind === 199 /* Block */) {
                    write(" ");
                }
                else {
                    writeLine();
                }
                write("while (");
                emit(node.expression);
                write(");");
            }
            function emitWhileStatement(node) {
                emitLoop(node, emitWhileStatementWorker);
            }
            function emitWhileStatementWorker(node, loop) {
                write("while (");
                emit(node.expression);
                write(")");
                if (loop) {
                    emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
                }
                else {
                    emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
                }
            }
            /**
             * Returns true if start of variable declaration list was emitted.
             * Returns false if nothing was written - this can happen for source file level variable declarations
             *     in system modules where such variable declarations are hoisted.
             */
            function tryEmitStartOfVariableDeclarationList(decl) {
                if (shouldHoistVariable(decl, /*checkIfSourceFileLevelDecl*/ true)) {
                    // variables in variable declaration list were already hoisted
                    return false;
                }
                if (convertedLoopState && (ts.getCombinedNodeFlags(decl) & 3072 /* BlockScoped */) === 0) {
                    // we are inside a converted loop - this can only happen in downlevel scenarios
                    // record names for all variable declarations
                    for (var _a = 0, _b = decl.declarations; _a < _b.length; _a++) {
                        var varDecl = _b[_a];
                        hoistVariableDeclarationFromLoop(convertedLoopState, varDecl);
                    }
                    return false;
                }
                emitStart(decl);
                if (decl && languageVersion >= 2 /* ES6 */) {
                    if (ts.isLet(decl)) {
                        write("let ");
                    }
                    else if (ts.isConst(decl)) {
                        write("const ");
                    }
                    else {
                        write("var ");
                    }
                }
                else {
                    write("var ");
                }
                // Note here we specifically dont emit end so that if we are going to emit binding pattern
                // we can alter the source map correctly
                return true;
            }
            function emitVariableDeclarationListSkippingUninitializedEntries(list) {
                var started = false;
                for (var _a = 0, _b = list.declarations; _a < _b.length; _a++) {
                    var decl = _b[_a];
                    if (!decl.initializer) {
                        continue;
                    }
                    if (!started) {
                        started = true;
                    }
                    else {
                        write(", ");
                    }
                    emit(decl);
                }
                return started;
            }
            function shouldConvertLoopBody(node) {
                return languageVersion < 2 /* ES6 */ &&
                    (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0;
            }
            function emitLoop(node, loopEmitter) {
                var shouldConvert = shouldConvertLoopBody(node);
                if (!shouldConvert) {
                    loopEmitter(node, /* convertedLoop*/ undefined);
                }
                else {
                    var loop = convertLoopBody(node);
                    if (node.parent.kind === 214 /* LabeledStatement */) {
                        // if parent of the loop was labeled statement - attach the label to loop skipping converted loop body
                        emitLabelAndColon(node.parent);
                    }
                    loopEmitter(node, loop);
                }
            }
            function convertLoopBody(node) {
                var functionName = makeUniqueName("_loop");
                var loopInitializer;
                switch (node.kind) {
                    case 206 /* ForStatement */:
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                        var initializer = node.initializer;
                        if (initializer && initializer.kind === 219 /* VariableDeclarationList */) {
                            loopInitializer = node.initializer;
                        }
                        break;
                }
                var loopParameters;
                var loopOutParameters;
                if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3072 /* BlockScoped */)) {
                    // if loop initializer contains block scoped variables - they should be passed to converted loop body as parameters
                    loopParameters = [];
                    for (var _a = 0, _b = loopInitializer.declarations; _a < _b.length; _a++) {
                        var varDeclaration = _b[_a];
                        processVariableDeclaration(varDeclaration.name);
                    }
                }
                var bodyIsBlock = node.statement.kind === 199 /* Block */;
                var paramList = loopParameters ? loopParameters.join(", ") : "";
                writeLine();
                write("var " + functionName + " = function(" + paramList + ")");
                var convertedOuterLoopState = convertedLoopState;
                convertedLoopState = { loopOutParameters: loopOutParameters };
                if (convertedOuterLoopState) {
                    // 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 (convertedOuterLoopState.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 = convertedOuterLoopState.argumentsName;
                    }
                    if (convertedOuterLoopState.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 = convertedOuterLoopState.thisName;
                    }
                    if (convertedOuterLoopState.hoistedLocalVariables) {
                        // we've already collected some non-block scoped variable declarations in enclosing loop
                        // use the same storage in nested loop
                        convertedLoopState.hoistedLocalVariables = convertedOuterLoopState.hoistedLocalVariables;
                    }
                }
                write(" {");
                writeLine();
                increaseIndent();
                if (bodyIsBlock) {
                    emitLines(node.statement.statements);
                }
                else {
                    emit(node.statement);
                }
                writeLine();
                // end of loop body -> copy out parameter
                copyLoopOutParameters(convertedLoopState, 1 /* ToOutParameter */, /*emitAsStatements*/ true);
                decreaseIndent();
                writeLine();
                write("};");
                writeLine();
                if (loopOutParameters) {
                    // declare variables to hold out params for loop body
                    write("var ");
                    for (var i = 0; i < loopOutParameters.length; i++) {
                        if (i !== 0) {
                            write(", ");
                        }
                        write(loopOutParameters[i].outParamName);
                    }
                    write(";");
                    writeLine();
                }
                if (convertedLoopState.argumentsName) {
                    // if alias for arguments is set
                    if (convertedOuterLoopState) {
                        // pass it to outer converted loop
                        convertedOuterLoopState.argumentsName = convertedLoopState.argumentsName;
                    }
                    else {
                        // this is top level converted loop and we need to create an alias for 'arguments' object
                        write("var " + convertedLoopState.argumentsName + " = arguments;");
                        writeLine();
                    }
                }
                if (convertedLoopState.thisName) {
                    // if alias for this is set
                    if (convertedOuterLoopState) {
                        // pass it to outer converted loop
                        convertedOuterLoopState.thisName = convertedLoopState.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'.
                        write("var " + convertedLoopState.thisName + " = this;");
                        writeLine();
                    }
                }
                if (convertedLoopState.hoistedLocalVariables) {
                    // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
                    if (convertedOuterLoopState) {
                        // pass them to outer converted loop
                        convertedOuterLoopState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
                    }
                    else {
                        // deduplicate and hoist collected variable declarations
                        write("var ");
                        var seen = void 0;
                        for (var _c = 0, _d = convertedLoopState.hoistedLocalVariables; _c < _d.length; _c++) {
                            var id = _d[_c];
                            // Don't initialize seen unless we have at least one element.
                            // Emit a comma to separate for all but the first element.
                            if (!seen) {
                                seen = {};
                            }
                            else {
                                write(", ");
                            }
                            if (!ts.hasProperty(seen, id.text)) {
                                emit(id);
                                seen[id.text] = id.text;
                            }
                        }
                        write(";");
                        writeLine();
                    }
                }
                var currentLoopState = convertedLoopState;
                convertedLoopState = convertedOuterLoopState;
                return { functionName: functionName, paramList: paramList, state: currentLoopState };
                function processVariableDeclaration(name) {
                    if (name.kind === 69 /* Identifier */) {
                        var nameText = isNameOfNestedBlockScopedRedeclarationOrCapturedBinding(name)
                            ? getGeneratedNameForNode(name)
                            : name.text;
                        loopParameters.push(nameText);
                        if (resolver.getNodeCheckFlags(name.parent) & 2097152 /* NeedsLoopOutParameter */) {
                            var reassignedVariable = { originalName: name, outParamName: makeUniqueName("out_" + nameText) };
                            (loopOutParameters || (loopOutParameters = [])).push(reassignedVariable);
                        }
                    }
                    else {
                        for (var _a = 0, _b = name.elements; _a < _b.length; _a++) {
                            var element = _b[_a];
                            processVariableDeclaration(element.name);
                        }
                    }
                }
            }
            function emitNormalLoopBody(node, emitAsEmbeddedStatement) {
                var saveAllowedNonLabeledJumps;
                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 */;
                }
                if (emitAsEmbeddedStatement) {
                    emitEmbeddedStatement(node.statement);
                }
                else if (node.statement.kind === 199 /* Block */) {
                    emitLines(node.statement.statements);
                }
                else {
                    writeLine();
                    emit(node.statement);
                }
                if (convertedLoopState) {
                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
                }
            }
            function copyLoopOutParameters(state, copyDirection, emitAsStatements) {
                if (state.loopOutParameters) {
                    for (var _a = 0, _b = state.loopOutParameters; _a < _b.length; _a++) {
                        var outParam = _b[_a];
                        if (copyDirection === 0 /* ToOriginal */) {
                            emitIdentifier(outParam.originalName);
                            write(" = " + outParam.outParamName);
                        }
                        else {
                            write(outParam.outParamName + " = ");
                            emitIdentifier(outParam.originalName);
                        }
                        if (emitAsStatements) {
                            write(";");
                            writeLine();
                        }
                        else {
                            write(", ");
                        }
                    }
                }
            }
            function emitConvertedLoopCall(loop, emitAsBlock) {
                if (emitAsBlock) {
                    write(" {");
                    writeLine();
                    increaseIndent();
                }
                // 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 = !(loop.state.nonLocalJumps & ~4 /* Continue */) &&
                    !loop.state.labeledNonLocalBreaks &&
                    !loop.state.labeledNonLocalContinues;
                var loopResult = makeUniqueName("state");
                if (!isSimpleLoop) {
                    write("var " + loopResult + " = ");
                }
                write(loop.functionName + "(" + loop.paramList + ");");
                writeLine();
                copyLoopOutParameters(loop.state, 0 /* ToOriginal */, /*emitAsStatements*/ true);
                if (!isSimpleLoop) {
                    // for non simple loops we need to store result returned from converted loop function and use it to do dispatching
                    // converted loop function can return:
                    // - object - used when body of the converted loop contains return statement. Property "value" of this object stores retuned value
                    // - string - used to dispatch jumps. "break" and "continue" are used to non-labeled jumps, other values are used to transfer control to
                    //   different labels
                    writeLine();
                    if (loop.state.nonLocalJumps & 8 /* Return */) {
                        write("if (typeof " + loopResult + " === \"object\") ");
                        if (convertedLoopState) {
                            // we are currently nested in another converted loop - return unwrapped result
                            write("return " + loopResult + ";");
                            // propagate 'hasReturn' flag to outer loop
                            convertedLoopState.nonLocalJumps |= 8 /* Return */;
                        }
                        else {
                            // top level converted loop - return unwrapped value
                            write("return " + loopResult + ".value;");
                        }
                        writeLine();
                    }
                    if (loop.state.nonLocalJumps & 2 /* Break */) {
                        write("if (" + loopResult + " === \"break\") break;");
                        writeLine();
                    }
                    // in case of labeled breaks emit code that either breaks to some known label inside outer loop or delegates jump decision to outer loop
                    emitDispatchTableForLabeledJumps(loopResult, loop.state, convertedLoopState);
                }
                if (emitAsBlock) {
                    writeLine();
                    decreaseIndent();
                    write("}");
                }
                function emitDispatchTableForLabeledJumps(loopResultVariable, currentLoop, outerLoop) {
                    if (!currentLoop.labeledNonLocalBreaks && !currentLoop.labeledNonLocalContinues) {
                        return;
                    }
                    write("switch(" + loopResultVariable + ") {");
                    increaseIndent();
                    emitDispatchEntriesForLabeledJumps(currentLoop.labeledNonLocalBreaks, /*isBreak*/ true, loopResultVariable, outerLoop);
                    emitDispatchEntriesForLabeledJumps(currentLoop.labeledNonLocalContinues, /*isBreak*/ false, loopResultVariable, outerLoop);
                    decreaseIndent();
                    writeLine();
                    write("}");
                }
                function emitDispatchEntriesForLabeledJumps(table, isBreak, loopResultVariable, outerLoop) {
                    if (!table) {
                        return;
                    }
                    for (var labelText in table) {
                        var labelMarker = table[labelText];
                        writeLine();
                        write("case \"" + labelMarker + "\": ");
                        // 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[labelText])) {
                            if (isBreak) {
                                write("break ");
                            }
                            else {
                                write("continue ");
                            }
                            write(labelText + ";");
                        }
                        else {
                            setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
                            write("return " + loopResultVariable + ";");
                        }
                    }
                }
            }
            function emitForStatement(node) {
                emitLoop(node, emitForStatementWorker);
            }
            function emitForStatementWorker(node, loop) {
                var endPos = emitToken(86 /* ForKeyword */, node.pos);
                write(" ");
                endPos = emitToken(17 /* OpenParenToken */, endPos);
                if (node.initializer && node.initializer.kind === 219 /* VariableDeclarationList */) {
                    var variableDeclarationList = node.initializer;
                    var startIsEmitted = tryEmitStartOfVariableDeclarationList(variableDeclarationList);
                    if (startIsEmitted) {
                        emitCommaList(variableDeclarationList.declarations);
                    }
                    else {
                        emitVariableDeclarationListSkippingUninitializedEntries(variableDeclarationList);
                    }
                }
                else if (node.initializer) {
                    emit(node.initializer);
                }
                write(";");
                emitOptional(" ", node.condition);
                write(";");
                emitOptional(" ", node.incrementor);
                write(")");
                if (loop) {
                    emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
                }
                else {
                    emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
                }
            }
            function emitForInOrForOfStatement(node) {
                if (languageVersion < 2 /* ES6 */ && node.kind === 208 /* ForOfStatement */) {
                    emitLoop(node, emitDownLevelForOfStatementWorker);
                }
                else {
                    emitLoop(node, emitForInOrForOfStatementWorker);
                }
            }
            function emitForInOrForOfStatementWorker(node, loop) {
                var endPos = emitToken(86 /* ForKeyword */, node.pos);
                write(" ");
                endPos = emitToken(17 /* OpenParenToken */, endPos);
                if (node.initializer.kind === 219 /* VariableDeclarationList */) {
                    var variableDeclarationList = node.initializer;
                    if (variableDeclarationList.declarations.length >= 1) {
                        tryEmitStartOfVariableDeclarationList(variableDeclarationList);
                        emit(variableDeclarationList.declarations[0]);
                    }
                }
                else {
                    emit(node.initializer);
                }
                if (node.kind === 207 /* ForInStatement */) {
                    write(" in ");
                }
                else {
                    write(" of ");
                }
                emit(node.expression);
                emitToken(18 /* CloseParenToken */, node.expression.end);
                if (loop) {
                    emitConvertedLoopCall(loop, /*emitAsBlock*/ true);
                }
                else {
                    emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ true);
                }
            }
            function emitDownLevelForOfStatementWorker(node, loop) {
                // The following ES6 code:
                //
                //    for (let v of expr) { }
                //
                // should be emitted as
                //
                //    for (let _i = 0, _a = expr; _i < _a.length; _i++) {
                //        let v = _a[_i];
                //    }
                //
                // where _a and _i are temps emitted to capture the RHS and the counter,
                // respectively.
                // When the left hand side is an expression instead of a let declaration,
                // the "let v" is not emitted.
                // When the left hand side is a let/const, the v is renamed if there is
                // another v in scope.
                // Note that all assignments to the LHS are emitted in the body, including
                // all destructuring.
                // Note also that because an extra statement is needed to assign to the LHS,
                // for-of bodies are always emitted as blocks.
                var endPos = emitToken(86 /* ForKeyword */, node.pos);
                write(" ");
                endPos = emitToken(17 /* OpenParenToken */, endPos);
                // Do not emit the LHS let declaration yet, because it might contain destructuring.
                // Do not call recordTempDeclaration because we are declaring the temps
                // right here. Recording means they will be declared later.
                // In the case where the user wrote an identifier as the RHS, like this:
                //
                //     for (let v of arr) { }
                //
                // we can't reuse 'arr' because it might be modified within the body of the loop.
                var counter = createTempVariable(268435456 /* _i */);
                var rhsReference = ts.createSynthesizedNode(69 /* Identifier */);
                rhsReference.text = node.expression.kind === 69 /* Identifier */ ?
                    makeUniqueName(node.expression.text) :
                    makeTempVariableName(0 /* Auto */);
                // This is the let keyword for the counter and rhsReference. The let keyword for
                // the LHS will be emitted inside the body.
                emitStart(node.expression);
                write("var ");
                // _i = 0
                emitNodeWithoutSourceMap(counter);
                write(" = 0");
                emitEnd(node.expression);
                // , _a = expr
                write(", ");
                emitStart(node.expression);
                emitNodeWithoutSourceMap(rhsReference);
                write(" = ");
                emitNodeWithoutSourceMap(node.expression);
                emitEnd(node.expression);
                write("; ");
                // _i < _a.length;
                emitStart(node.expression);
                emitNodeWithoutSourceMap(counter);
                write(" < ");
                emitNodeWithCommentsAndWithoutSourcemap(rhsReference);
                write(".length");
                emitEnd(node.expression);
                write("; ");
                // _i++)
                emitStart(node.expression);
                emitNodeWithoutSourceMap(counter);
                write("++");
                emitEnd(node.expression);
                emitToken(18 /* CloseParenToken */, node.expression.end);
                // Body
                write(" {");
                writeLine();
                increaseIndent();
                // Initialize LHS
                // let v = _a[_i];
                var rhsIterationValue = createElementAccessExpression(rhsReference, counter);
                emitStart(node.initializer);
                if (node.initializer.kind === 219 /* VariableDeclarationList */) {
                    write("var ");
                    var variableDeclarationList = node.initializer;
                    if (variableDeclarationList.declarations.length > 0) {
                        var declaration = variableDeclarationList.declarations[0];
                        if (ts.isBindingPattern(declaration.name)) {
                            // This works whether the declaration is a var, let, or const.
                            // It will use rhsIterationValue _a[_i] as the initializer.
                            emitDestructuring(declaration, /*isAssignmentExpressionStatement*/ false, rhsIterationValue);
                        }
                        else {
                            // The following call does not include the initializer, so we have
                            // to emit it separately.
                            emitNodeWithCommentsAndWithoutSourcemap(declaration);
                            write(" = ");
                            emitNodeWithoutSourceMap(rhsIterationValue);
                        }
                    }
                    else {
                        // It's an empty declaration list. This can only happen in an error case, if the user wrote
                        //     for (let of []) {}
                        emitNodeWithoutSourceMap(createTempVariable(0 /* Auto */));
                        write(" = ");
                        emitNodeWithoutSourceMap(rhsIterationValue);
                    }
                }
                else {
                    // Initializer is an expression. Emit the expression in the body, so that it's
                    // evaluated on every iteration.
                    var assignmentExpression = createBinaryExpression(node.initializer, 56 /* EqualsToken */, rhsIterationValue, /*startsOnNewLine*/ false);
                    if (node.initializer.kind === 170 /* ArrayLiteralExpression */ || node.initializer.kind === 171 /* ObjectLiteralExpression */) {
                        // This is a destructuring pattern, so call emitDestructuring instead of emit. Calling emit will not work, because it will cause
                        // the BinaryExpression to be passed in instead of the expression statement, which will cause emitDestructuring to crash.
                        emitDestructuring(assignmentExpression, /*isAssignmentExpressionStatement*/ true, /*value*/ undefined);
                    }
                    else {
                        emitNodeWithCommentsAndWithoutSourcemap(assignmentExpression);
                    }
                }
                emitEnd(node.initializer);
                write(";");
                if (loop) {
                    writeLine();
                    emitConvertedLoopCall(loop, /*emitAsBlock*/ false);
                }
                else {
                    emitNormalLoopBody(node, /*emitAsEmbeddedStatement*/ false);
                }
                writeLine();
                decreaseIndent();
                write("}");
            }
            function emitBreakOrContinueStatement(node) {
                if (convertedLoopState) {
                    // check if we can emit break\continue as is
                    // it is possible if either
                    //   - break\continue is statement 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 === 210 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
                    var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels[node.label.text]) ||
                        (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
                    if (!canUseBreakOrContinue) {
                        write("return ");
                        // explicit exit from loop -> copy out parameters
                        copyLoopOutParameters(convertedLoopState, 1 /* ToOutParameter */, /*emitAsStatements*/ false);
                        if (!node.label) {
                            if (node.kind === 210 /* BreakStatement */) {
                                convertedLoopState.nonLocalJumps |= 2 /* Break */;
                                write("\"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.
                                write("\"continue\";");
                            }
                        }
                        else {
                            var labelMarker = void 0;
                            if (node.kind === 210 /* BreakStatement */) {
                                labelMarker = "break-" + node.label.text;
                                setLabeledJump(convertedLoopState, /*isBreak*/ true, node.label.text, labelMarker);
                            }
                            else {
                                labelMarker = "continue-" + node.label.text;
                                setLabeledJump(convertedLoopState, /*isBreak*/ false, node.label.text, labelMarker);
                            }
                            write("\"" + labelMarker + "\";");
                        }
                        return;
                    }
                }
                emitToken(node.kind === 210 /* BreakStatement */ ? 70 /* BreakKeyword */ : 75 /* ContinueKeyword */, node.pos);
                emitOptional(" ", node.label);
                write(";");
            }
            function emitReturnStatement(node) {
                if (convertedLoopState) {
                    convertedLoopState.nonLocalJumps |= 8 /* Return */;
                    write("return { value: ");
                    if (node.expression) {
                        emit(node.expression);
                    }
                    else {
                        write("void 0");
                    }
                    write(" };");
                    return;
                }
                emitToken(94 /* ReturnKeyword */, node.pos);
                emitOptional(" ", node.expression);
                write(";");
            }
            function emitWithStatement(node) {
                write("with (");
                emit(node.expression);
                write(")");
                emitEmbeddedStatement(node.statement);
            }
            function emitSwitchStatement(node) {
                var endPos = emitToken(96 /* SwitchKeyword */, node.pos);
                write(" ");
                emitToken(17 /* OpenParenToken */, endPos);
                emit(node.expression);
                endPos = emitToken(18 /* CloseParenToken */, node.expression.end);
                write(" ");
                var saveAllowedNonLabeledJumps;
                if (convertedLoopState) {
                    saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                    // for switch statement allow only non-labeled break
                    convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
                }
                emitCaseBlock(node.caseBlock, endPos);
                if (convertedLoopState) {
                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
                }
            }
            function emitCaseBlock(node, startPos) {
                emitToken(15 /* OpenBraceToken */, startPos);
                increaseIndent();
                emitLines(node.clauses);
                decreaseIndent();
                writeLine();
                emitToken(16 /* CloseBraceToken */, node.clauses.end);
            }
            function nodeStartPositionsAreOnSameLine(node1, node2) {
                return ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node1.pos)) ===
                    ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
            }
            function nodeEndPositionsAreOnSameLine(node1, node2) {
                return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
                    ts.getLineOfLocalPositionFromLineMap(currentLineMap, node2.end);
            }
            function nodeEndIsOnSameLineAsNodeStart(node1, node2) {
                return ts.getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) ===
                    ts.getLineOfLocalPositionFromLineMap(currentLineMap, ts.skipTrivia(currentText, node2.pos));
            }
            function emitCaseOrDefaultClause(node) {
                if (node.kind === 249 /* CaseClause */) {
                    write("case ");
                    emit(node.expression);
                    write(":");
                }
                else {
                    write("default:");
                }
                if (node.statements.length === 1 && nodeStartPositionsAreOnSameLine(node, node.statements[0])) {
                    write(" ");
                    emit(node.statements[0]);
                }
                else {
                    increaseIndent();
                    emitLines(node.statements);
                    decreaseIndent();
                }
            }
            function emitThrowStatement(node) {
                write("throw ");
                emit(node.expression);
                write(";");
            }
            function emitTryStatement(node) {
                write("try ");
                emit(node.tryBlock);
                emit(node.catchClause);
                if (node.finallyBlock) {
                    writeLine();
                    write("finally ");
                    emit(node.finallyBlock);
                }
            }
            function emitCatchClause(node) {
                writeLine();
                var endPos = emitToken(72 /* CatchKeyword */, node.pos);
                write(" ");
                emitToken(17 /* OpenParenToken */, endPos);
                emit(node.variableDeclaration);
                emitToken(18 /* CloseParenToken */, node.variableDeclaration ? node.variableDeclaration.end : endPos);
                write(" ");
                emitBlock(node.block);
            }
            function emitDebuggerStatement(node) {
                emitToken(76 /* DebuggerKeyword */, node.pos);
                write(";");
            }
            function emitLabelAndColon(node) {
                emit(node.label);
                write(": ");
            }
            function emitLabeledStatement(node) {
                if (!ts.isIterationStatement(node.statement, /* lookInLabeledStatements */ false) || !shouldConvertLoopBody(node.statement)) {
                    emitLabelAndColon(node);
                }
                if (convertedLoopState) {
                    if (!convertedLoopState.labels) {
                        convertedLoopState.labels = {};
                    }
                    convertedLoopState.labels[node.label.text] = node.label.text;
                }
                emit(node.statement);
                if (convertedLoopState) {
                    convertedLoopState.labels[node.label.text] = undefined;
                }
            }
            function getContainingModule(node) {
                do {
                    node = node.parent;
                } while (node && node.kind !== 225 /* ModuleDeclaration */);
                return node;
            }
            function emitContainingModuleName(node) {
                var container = getContainingModule(node);
                write(container ? getGeneratedNameForNode(container) : "exports");
            }
            function emitModuleMemberName(node) {
                emitStart(node.name);
                if (ts.getCombinedNodeFlags(node) & 1 /* Export */) {
                    var container = getContainingModule(node);
                    if (container) {
                        write(getGeneratedNameForNode(container));
                        write(".");
                    }
                    else if (modulekind !== ts.ModuleKind.ES6 && modulekind !== ts.ModuleKind.System) {
                        write("exports.");
                    }
                }
                emitNodeWithCommentsAndWithoutSourcemap(node.name);
                emitEnd(node.name);
            }
            function createVoidZero() {
                var zero = ts.createSynthesizedNode(8 /* NumericLiteral */);
                zero.text = "0";
                var result = ts.createSynthesizedNode(183 /* VoidExpression */);
                result.expression = zero;
                return result;
            }
            function emitEs6ExportDefaultCompat(node) {
                if (node.parent.kind === 256 /* SourceFile */) {
                    ts.Debug.assert(!!(node.flags & 512 /* Default */) || node.kind === 235 /* ExportAssignment */);
                    // only allow export default at a source file level
                    if (modulekind === ts.ModuleKind.CommonJS || modulekind === ts.ModuleKind.AMD || modulekind === ts.ModuleKind.UMD) {
                        if (!isEs6Module) {
                            if (languageVersion !== 0 /* ES3 */) {
                                // default value of configurable, enumerable, writable are `false`.
                                write('Object.defineProperty(exports, "__esModule", { value: true });');
                                writeLine();
                            }
                            else {
                                write("exports.__esModule = true;");
                                writeLine();
                            }
                        }
                    }
                }
            }
            function emitExportMemberAssignment(node) {
                if (node.flags & 1 /* Export */) {
                    writeLine();
                    emitStart(node);
                    // emit call to exporter only for top level nodes
                    if (modulekind === ts.ModuleKind.System && node.parent === currentSourceFile) {
                        // emit export default <smth> as
                        // export("default", <smth>)
                        write(exportFunctionForFile + "(\"");
                        if (node.flags & 512 /* Default */) {
                            write("default");
                        }
                        else {
                            emitNodeWithCommentsAndWithoutSourcemap(node.name);
                        }
                        write("\", ");
                        emitDeclarationName(node);
                        write(")");
                    }
                    else {
                        if (node.flags & 512 /* Default */) {
                            emitEs6ExportDefaultCompat(node);
                            if (languageVersion === 0 /* ES3 */) {
                                write('exports["default"]');
                            }
                            else {
                                write("exports.default");
                            }
                        }
                        else {
                            emitModuleMemberName(node);
                        }
                        write(" = ");
                        emitDeclarationName(node);
                    }
                    emitEnd(node);
                    write(";");
                }
            }
            function emitExportMemberAssignments(name) {
                if (modulekind === ts.ModuleKind.System) {
                    return;
                }
                if (!exportEquals && exportSpecifiers && ts.hasProperty(exportSpecifiers, name.text)) {
                    for (var _a = 0, _b = exportSpecifiers[name.text]; _a < _b.length; _a++) {
                        var specifier = _b[_a];
                        writeLine();
                        emitStart(specifier.name);
                        emitContainingModuleName(specifier);
                        write(".");
                        emitNodeWithCommentsAndWithoutSourcemap(specifier.name);
                        emitEnd(specifier.name);
                        write(" = ");
                        emitExpressionIdentifier(name);
                        write(";");
                    }
                }
            }
            function emitExportSpecifierInSystemModule(specifier) {
                ts.Debug.assert(modulekind === ts.ModuleKind.System);
                if (!resolver.getReferencedValueDeclaration(specifier.propertyName || specifier.name) && !resolver.isValueAliasDeclaration(specifier)) {
                    return;
                }
                writeLine();
                emitStart(specifier.name);
                write(exportFunctionForFile + "(\"");
                emitNodeWithCommentsAndWithoutSourcemap(specifier.name);
                write("\", ");
                emitExpressionIdentifier(specifier.propertyName || specifier.name);
                write(")");
                emitEnd(specifier.name);
                write(";");
            }
            /**
             * Emit an assignment to a given identifier, 'name', with a given expression, 'value'.
             * @param name an identifier as a left-hand-side operand of the assignment
             * @param value an expression as a right-hand-side operand of the assignment
             * @param shouldEmitCommaBeforeAssignment a boolean indicating whether to prefix an assignment with comma
             */
            function emitAssignment(name, value, shouldEmitCommaBeforeAssignment, nodeForSourceMap) {
                if (shouldEmitCommaBeforeAssignment) {
                    write(", ");
                }
                var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(name);
                if (exportChanged) {
                    write(exportFunctionForFile + "(\"");
                    emitNodeWithCommentsAndWithoutSourcemap(name);
                    write("\", ");
                }
                var isVariableDeclarationOrBindingElement = name.parent && (name.parent.kind === 218 /* VariableDeclaration */ || name.parent.kind === 169 /* BindingElement */);
                // If this is first var declaration, we need to start at var/let/const keyword instead
                // otherwise use nodeForSourceMap as the start position
                emitStart(isFirstVariableDeclaration(nodeForSourceMap) ? nodeForSourceMap.parent : nodeForSourceMap);
                withTemporaryNoSourceMap(function () {
                    if (isVariableDeclarationOrBindingElement) {
                        emitModuleMemberName(name.parent);
                    }
                    else {
                        emit(name);
                    }
                    write(" = ");
                    emit(value);
                });
                emitEnd(nodeForSourceMap, /*stopOverridingSpan*/ true);
                if (exportChanged) {
                    write(")");
                }
            }
            /**
             * Create temporary variable, emit an assignment of the variable the given expression
             * @param expression an expression to assign to the newly created temporary variable
             * @param canDefineTempVariablesInPlace a boolean indicating whether you can define the temporary variable at an assignment location
             * @param shouldEmitCommaBeforeAssignment a boolean indicating whether an assignment should prefix with comma
             */
            function emitTempVariableAssignment(expression, canDefineTempVariablesInPlace, shouldEmitCommaBeforeAssignment, sourceMapNode) {
                var identifier = createTempVariable(0 /* Auto */);
                if (!canDefineTempVariablesInPlace) {
                    recordTempDeclaration(identifier);
                }
                emitAssignment(identifier, expression, shouldEmitCommaBeforeAssignment, sourceMapNode || expression.parent);
                return identifier;
            }
            function isFirstVariableDeclaration(root) {
                return root.kind === 218 /* VariableDeclaration */ &&
                    root.parent.kind === 219 /* VariableDeclarationList */ &&
                    root.parent.declarations[0] === root;
            }
            function emitDestructuring(root, isAssignmentExpressionStatement, value) {
                var emitCount = 0;
                // An exported declaration is actually emitted as an assignment (to a property on the module object), so
                // temporary variables in an exported declaration need to have real declarations elsewhere
                // Also temporary variables should be explicitly allocated for source level declarations when module target is system
                // because actual variable declarations are hoisted
                var canDefineTempVariablesInPlace = false;
                if (root.kind === 218 /* VariableDeclaration */) {
                    var isExported = ts.getCombinedNodeFlags(root) & 1 /* Export */;
                    var isSourceLevelForSystemModuleKind = shouldHoistDeclarationInSystemJsModule(root);
                    canDefineTempVariablesInPlace = !isExported && !isSourceLevelForSystemModuleKind;
                }
                else if (root.kind === 142 /* Parameter */) {
                    canDefineTempVariablesInPlace = true;
                }
                if (root.kind === 187 /* BinaryExpression */) {
                    emitAssignmentExpression(root);
                }
                else {
                    ts.Debug.assert(!isAssignmentExpressionStatement);
                    // If first variable declaration of variable statement correct the start location
                    if (isFirstVariableDeclaration(root)) {
                        // Use emit location of "var " as next emit start entry
                        sourceMap.changeEmitSourcePos();
                    }
                    emitBindingElement(root, value);
                }
                /**
                 * 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, 'expr' will be returned if it is just an identifier.
                 *
                 * @param expr 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.
                 */
                function ensureIdentifier(expr, reuseIdentifierExpressions, sourceMapNode) {
                    if (expr.kind === 69 /* Identifier */ && reuseIdentifierExpressions) {
                        return expr;
                    }
                    var identifier = emitTempVariableAssignment(expr, canDefineTempVariablesInPlace, emitCount > 0, sourceMapNode);
                    emitCount++;
                    return identifier;
                }
                function createDefaultValueCheck(value, defaultValue, sourceMapNode) {
                    // The value expression will be evaluated twice, so for anything but a simple identifier
                    // we need to generate a temporary variable
                    // If the temporary variable needs to be emitted use the source Map node for assignment of that statement
                    value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, sourceMapNode);
                    // Return the expression 'value === void 0 ? defaultValue : value'
                    var equals = ts.createSynthesizedNode(187 /* BinaryExpression */);
                    equals.left = value;
                    equals.operatorToken = ts.createSynthesizedNode(32 /* EqualsEqualsEqualsToken */);
                    equals.right = createVoidZero();
                    return createConditionalExpression(equals, defaultValue, value);
                }
                function createConditionalExpression(condition, whenTrue, whenFalse) {
                    var cond = ts.createSynthesizedNode(188 /* ConditionalExpression */);
                    cond.condition = condition;
                    cond.questionToken = ts.createSynthesizedNode(53 /* QuestionToken */);
                    cond.whenTrue = whenTrue;
                    cond.colonToken = ts.createSynthesizedNode(54 /* ColonToken */);
                    cond.whenFalse = whenFalse;
                    return cond;
                }
                function createNumericLiteral(value) {
                    var node = ts.createSynthesizedNode(8 /* NumericLiteral */);
                    node.text = "" + value;
                    return node;
                }
                function createPropertyAccessForDestructuringProperty(object, propName) {
                    var index;
                    var nameIsComputed = propName.kind === 140 /* ComputedPropertyName */;
                    if (nameIsComputed) {
                        // TODO to handle when we look into sourcemaps for computed properties, for now use propName
                        index = ensureIdentifier(propName.expression, /*reuseIdentifierExpressions*/ false, propName);
                    }
                    else {
                        // We create a synthetic copy of the identifier in order to avoid the rewriting that might
                        // otherwise occur when the identifier is emitted.
                        index = ts.createSynthesizedNode(propName.kind);
                        // We need to unescape identifier here because when parsing an identifier prefixing with "__"
                        // the parser need to append "_" in order to escape colliding with magic identifiers such as "__proto__"
                        // Therefore, in order to correctly emit identifiers that are written in original TypeScript file,
                        // we will unescapeIdentifier to remove additional underscore (if no underscore is added, the function will return original input string)
                        index.text = ts.unescapeIdentifier(propName.text);
                    }
                    return !nameIsComputed && index.kind === 69 /* Identifier */
                        ? createPropertyAccessExpression(object, index)
                        : createElementAccessExpression(object, index);
                }
                function createSliceCall(value, sliceIndex) {
                    var call = ts.createSynthesizedNode(174 /* CallExpression */);
                    var sliceIdentifier = ts.createSynthesizedNode(69 /* Identifier */);
                    sliceIdentifier.text = "slice";
                    call.expression = createPropertyAccessExpression(value, sliceIdentifier);
                    call.arguments = ts.createSynthesizedNodeArray();
                    call.arguments[0] = createNumericLiteral(sliceIndex);
                    return call;
                }
                function emitObjectLiteralAssignment(target, value, sourceMapNode) {
                    var properties = target.properties;
                    if (properties.length !== 1) {
                        // For anything but a single element destructuring we need to generate a temporary
                        // to ensure value is evaluated exactly once.
                        // When doing so we want to highlight the passed in source map node since thats the one needing this temp assignment
                        value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, sourceMapNode);
                    }
                    for (var _a = 0, properties_5 = properties; _a < properties_5.length; _a++) {
                        var p = properties_5[_a];
                        if (p.kind === 253 /* PropertyAssignment */ || p.kind === 254 /* ShorthandPropertyAssignment */) {
                            var propName = p.name;
                            var target_1 = p.kind === 254 /* ShorthandPropertyAssignment */ ? p : p.initializer || propName;
                            // Assignment for target = value.propName should highlight whole property, hence use p as source map node
                            emitDestructuringAssignment(target_1, createPropertyAccessForDestructuringProperty(value, propName), p);
                        }
                    }
                }
                function emitArrayLiteralAssignment(target, value, sourceMapNode) {
                    var elements = target.elements;
                    if (elements.length !== 1) {
                        // For anything but a single element destructuring we need to generate a temporary
                        // to ensure value is evaluated exactly once.
                        // When doing so we want to highlight the passed in source map node since thats the one needing this temp assignment
                        value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, sourceMapNode);
                    }
                    for (var i = 0; i < elements.length; i++) {
                        var e = elements[i];
                        if (e.kind !== 193 /* OmittedExpression */) {
                            // Assignment for target = value.propName should highlight whole property, hence use e as source map node
                            if (e.kind !== 191 /* SpreadElementExpression */) {
                                emitDestructuringAssignment(e, createElementAccessExpression(value, createNumericLiteral(i)), e);
                            }
                            else if (i === elements.length - 1) {
                                emitDestructuringAssignment(e.expression, createSliceCall(value, i), e);
                            }
                        }
                    }
                }
                function emitDestructuringAssignment(target, value, sourceMapNode) {
                    // When emitting target = value use source map node to highlight, including any temporary assignments needed for this
                    if (target.kind === 254 /* ShorthandPropertyAssignment */) {
                        if (target.objectAssignmentInitializer) {
                            value = createDefaultValueCheck(value, target.objectAssignmentInitializer, sourceMapNode);
                        }
                        target = target.name;
                    }
                    else if (target.kind === 187 /* BinaryExpression */ && target.operatorToken.kind === 56 /* EqualsToken */) {
                        value = createDefaultValueCheck(value, target.right, sourceMapNode);
                        target = target.left;
                    }
                    if (target.kind === 171 /* ObjectLiteralExpression */) {
                        emitObjectLiteralAssignment(target, value, sourceMapNode);
                    }
                    else if (target.kind === 170 /* ArrayLiteralExpression */) {
                        emitArrayLiteralAssignment(target, value, sourceMapNode);
                    }
                    else {
                        emitAssignment(target, value, /*shouldEmitCommaBeforeAssignment*/ emitCount > 0, sourceMapNode);
                        emitCount++;
                    }
                }
                function emitAssignmentExpression(root) {
                    var target = root.left;
                    var value = root.right;
                    if (ts.isEmptyObjectLiteralOrArrayLiteral(target)) {
                        emit(value);
                    }
                    else if (isAssignmentExpressionStatement) {
                        // Source map node for root.left = root.right is root
                        // but if root is synthetic, which could be in below case, use the target which is { a }
                        // for ({a} of {a: string}) {
                        // }
                        emitDestructuringAssignment(target, value, ts.nodeIsSynthesized(root) ? target : root);
                    }
                    else {
                        if (root.parent.kind !== 178 /* ParenthesizedExpression */) {
                            write("(");
                        }
                        // Temporary assignment needed to emit root should highlight whole binary expression
                        value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, root);
                        // Source map node for root.left = root.right is root
                        emitDestructuringAssignment(target, value, root);
                        write(", ");
                        emit(value);
                        if (root.parent.kind !== 178 /* ParenthesizedExpression */) {
                            write(")");
                        }
                    }
                }
                function emitBindingElement(target, value) {
                    // Any temporary assignments needed to emit target = value should point to target
                    if (target.initializer) {
                        // Combine value and initializer
                        value = value ? createDefaultValueCheck(value, target.initializer, target) : target.initializer;
                    }
                    else if (!value) {
                        // Use 'void 0' in absence of value and initializer
                        value = createVoidZero();
                    }
                    if (ts.isBindingPattern(target.name)) {
                        var pattern = target.name;
                        var elements = pattern.elements;
                        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.
                            value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ numElements !== 0, target);
                        }
                        for (var i = 0; i < numElements; i++) {
                            var element = elements[i];
                            if (pattern.kind === 167 /* ObjectBindingPattern */) {
                                // Rewrite element to a declaration with an initializer that fetches property
                                var propName = element.propertyName || element.name;
                                emitBindingElement(element, createPropertyAccessForDestructuringProperty(value, propName));
                            }
                            else if (element.kind !== 193 /* OmittedExpression */) {
                                if (!element.dotDotDotToken) {
                                    // Rewrite element to a declaration that accesses array element at index i
                                    emitBindingElement(element, createElementAccessExpression(value, createNumericLiteral(i)));
                                }
                                else if (i === numElements - 1) {
                                    emitBindingElement(element, createSliceCall(value, i));
                                }
                            }
                        }
                    }
                    else {
                        emitAssignment(target.name, value, /*shouldEmitCommaBeforeAssignment*/ emitCount > 0, target);
                        emitCount++;
                    }
                }
            }
            function emitVariableDeclaration(node) {
                if (ts.isBindingPattern(node.name)) {
                    var isExported = ts.getCombinedNodeFlags(node) & 1 /* Export */;
                    if (languageVersion >= 2 /* ES6 */ && (!isExported || modulekind === ts.ModuleKind.ES6)) {
                        // emit ES6 destructuring only if target module is ES6 or variable is not exported
                        // exported variables in CJS/AMD are prefixed with 'exports.' so result javascript { exports.toString } = 1; is illegal
                        var isTopLevelDeclarationInSystemModule = modulekind === ts.ModuleKind.System &&
                            shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ true);
                        if (isTopLevelDeclarationInSystemModule) {
                            // In System modules top level variables are hoisted
                            // so variable declarations with destructuring are turned into destructuring assignments.
                            // As a result, they will need parentheses to disambiguate object binding assignments from blocks.
                            write("(");
                        }
                        emit(node.name);
                        emitOptional(" = ", node.initializer);
                        if (isTopLevelDeclarationInSystemModule) {
                            write(")");
                        }
                    }
                    else {
                        emitDestructuring(node, /*isAssignmentExpressionStatement*/ false);
                    }
                }
                else {
                    var initializer = node.initializer;
                    if (!initializer &&
                        languageVersion < 2 /* ES6 */ &&
                        // for names - binding patterns that lack initializer 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
                        node.name.kind === 69 /* Identifier */) {
                        var container = ts.getEnclosingBlockScopeContainer(node);
                        var flags = resolver.getNodeCheckFlags(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
                        // NOTES:
                        // 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 isCapturedInFunction = flags & 131072 /* CapturedBlockScopedBinding */;
                        var isDeclaredInLoop = flags & 262144 /* BlockScopedBindingInLoop */;
                        var emittedAsTopLevel = ts.isBlockScopedContainerTopLevel(container) ||
                            (isCapturedInFunction && isDeclaredInLoop && container.kind === 199 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false));
                        var emittedAsNestedLetDeclaration = ts.getCombinedNodeFlags(node) & 1024 /* Let */ &&
                            !emittedAsTopLevel;
                        var emitExplicitInitializer = emittedAsNestedLetDeclaration &&
                            container.kind !== 207 /* ForInStatement */ &&
                            container.kind !== 208 /* ForOfStatement */ &&
                            (!resolver.isDeclarationWithCollidingName(node) ||
                                (isDeclaredInLoop && !isCapturedInFunction && !ts.isIterationStatement(container, /*lookInLabeledStatements*/ false)));
                        if (emitExplicitInitializer) {
                            initializer = createVoidZero();
                        }
                    }
                    var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.name);
                    if (exportChanged) {
                        write(exportFunctionForFile + "(\"");
                        emitNodeWithCommentsAndWithoutSourcemap(node.name);
                        write("\", ");
                    }
                    emitModuleMemberName(node);
                    emitOptional(" = ", initializer);
                    if (exportChanged) {
                        write(")");
                    }
                }
            }
            function emitExportVariableAssignments(node) {
                if (node.kind === 193 /* OmittedExpression */) {
                    return;
                }
                var name = node.name;
                if (name.kind === 69 /* Identifier */) {
                    emitExportMemberAssignments(name);
                }
                else if (ts.isBindingPattern(name)) {
                    ts.forEach(name.elements, emitExportVariableAssignments);
                }
            }
            function isES6ExportedDeclaration(node) {
                return !!(node.flags & 1 /* Export */) &&
                    modulekind === ts.ModuleKind.ES6 &&
                    node.parent.kind === 256 /* SourceFile */;
            }
            function emitVariableStatement(node) {
                var startIsEmitted = false;
                if (node.flags & 1 /* Export */) {
                    if (isES6ExportedDeclaration(node)) {
                        // Exported ES6 module member
                        write("export ");
                        startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
                    }
                }
                else {
                    startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
                }
                if (startIsEmitted) {
                    emitCommaList(node.declarationList.declarations);
                    write(";");
                }
                else {
                    var atLeastOneItem = emitVariableDeclarationListSkippingUninitializedEntries(node.declarationList);
                    if (atLeastOneItem) {
                        write(";");
                    }
                }
                if (modulekind !== ts.ModuleKind.ES6 && node.parent === currentSourceFile) {
                    ts.forEach(node.declarationList.declarations, emitExportVariableAssignments);
                }
            }
            function shouldEmitLeadingAndTrailingCommentsForVariableStatement(node) {
                // If we're not exporting the variables, there's nothing special here.
                // Always emit comments for these nodes.
                if (!(node.flags & 1 /* Export */)) {
                    return true;
                }
                // If we are exporting, but it's a top-level ES6 module exports,
                // we'll emit the declaration list verbatim, so emit comments too.
                if (isES6ExportedDeclaration(node)) {
                    return true;
                }
                // Otherwise, only emit if we have at least one initializer present.
                for (var _a = 0, _b = node.declarationList.declarations; _a < _b.length; _a++) {
                    var declaration = _b[_a];
                    if (declaration.initializer) {
                        return true;
                    }
                }
                return false;
            }
            function emitParameter(node) {
                if (languageVersion < 2 /* ES6 */) {
                    if (ts.isBindingPattern(node.name)) {
                        var name_29 = createTempVariable(0 /* Auto */);
                        if (!tempParameters) {
                            tempParameters = [];
                        }
                        tempParameters.push(name_29);
                        emit(name_29);
                    }
                    else {
                        emit(node.name);
                    }
                }
                else {
                    if (node.dotDotDotToken) {
                        write("...");
                    }
                    emit(node.name);
                    emitOptional(" = ", node.initializer);
                }
            }
            function emitDefaultValueAssignments(node) {
                if (languageVersion < 2 /* ES6 */) {
                    var tempIndex_1 = 0;
                    ts.forEach(node.parameters, function (parameter) {
                        // A rest parameter cannot have a binding pattern or an initializer,
                        // so let's just ignore it.
                        if (parameter.dotDotDotToken) {
                            return;
                        }
                        var paramName = parameter.name, initializer = parameter.initializer;
                        if (ts.isBindingPattern(paramName)) {
                            // 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.
                            var hasBindingElements = paramName.elements.length > 0;
                            if (hasBindingElements || initializer) {
                                writeLine();
                                write("var ");
                                if (hasBindingElements) {
                                    emitDestructuring(parameter, /*isAssignmentExpressionStatement*/ false, tempParameters[tempIndex_1]);
                                }
                                else {
                                    emit(tempParameters[tempIndex_1]);
                                    write(" = ");
                                    emit(initializer);
                                }
                                write(";");
                            }
                            // Regardless of whether we will emit a var declaration for the binding pattern, we generate the temporary
                            // variable for the parameter (see: emitParameter)
                            tempIndex_1++;
                        }
                        else if (initializer) {
                            writeLine();
                            emitStart(parameter);
                            write("if (");
                            emitNodeWithoutSourceMap(paramName);
                            write(" === void 0)");
                            emitEnd(parameter);
                            write(" { ");
                            emitStart(parameter);
                            emitNodeWithCommentsAndWithoutSourcemap(paramName);
                            write(" = ");
                            emitNodeWithCommentsAndWithoutSourcemap(initializer);
                            emitEnd(parameter);
                            write("; }");
                        }
                    });
                }
            }
            function emitRestParameter(node) {
                if (languageVersion < 2 /* ES6 */ && ts.hasDeclaredRestParameter(node)) {
                    var restIndex = node.parameters.length - 1;
                    var restParam = node.parameters[restIndex];
                    // A rest parameter cannot have a binding pattern, so let's just ignore it if it does.
                    if (ts.isBindingPattern(restParam.name)) {
                        return;
                    }
                    var tempName = createTempVariable(268435456 /* _i */).text;
                    writeLine();
                    emitLeadingComments(restParam);
                    emitStart(restParam);
                    write("var ");
                    emitNodeWithCommentsAndWithoutSourcemap(restParam.name);
                    write(" = [];");
                    emitEnd(restParam);
                    emitTrailingComments(restParam);
                    writeLine();
                    write("for (");
                    emitStart(restParam);
                    write("var " + tempName + " = " + restIndex + ";");
                    emitEnd(restParam);
                    write(" ");
                    emitStart(restParam);
                    write(tempName + " < arguments.length;");
                    emitEnd(restParam);
                    write(" ");
                    emitStart(restParam);
                    write(tempName + "++");
                    emitEnd(restParam);
                    write(") {");
                    increaseIndent();
                    writeLine();
                    emitStart(restParam);
                    emitNodeWithCommentsAndWithoutSourcemap(restParam.name);
                    write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];");
                    emitEnd(restParam);
                    decreaseIndent();
                    writeLine();
                    write("}");
                }
            }
            function emitAccessor(node) {
                write(node.kind === 149 /* GetAccessor */ ? "get " : "set ");
                emit(node.name);
                emitSignatureAndBody(node);
            }
            function shouldEmitAsArrowFunction(node) {
                return node.kind === 180 /* ArrowFunction */ && languageVersion >= 2 /* ES6 */;
            }
            function emitDeclarationName(node) {
                if (node.name) {
                    emitNodeWithCommentsAndWithoutSourcemap(node.name);
                }
                else {
                    write(getGeneratedNameForNode(node));
                }
            }
            function shouldEmitFunctionName(node) {
                if (node.kind === 179 /* FunctionExpression */) {
                    // Emit name if one is present
                    return !!node.name;
                }
                if (node.kind === 220 /* FunctionDeclaration */) {
                    // Emit name if one is present, or emit generated name in down-level case (for export default case)
                    return !!node.name || modulekind !== ts.ModuleKind.ES6;
                }
            }
            function emitFunctionDeclaration(node) {
                if (ts.nodeIsMissing(node.body)) {
                    return emitCommentsOnNotEmittedNode(node);
                }
                // TODO (yuisu) : we should not have special cases to condition emitting comments
                // but have one place to fix check for these conditions.
                var kind = node.kind, parent = node.parent;
                if (kind !== 147 /* MethodDeclaration */ &&
                    kind !== 146 /* MethodSignature */ &&
                    parent &&
                    parent.kind !== 253 /* PropertyAssignment */ &&
                    parent.kind !== 174 /* CallExpression */ &&
                    parent.kind !== 170 /* ArrayLiteralExpression */) {
                    // 1. Methods will emit comments at their assignment declaration sites.
                    //
                    // 2. If the function is a property of object literal, emitting leading-comments
                    //    is done by emitNodeWithoutSourceMap which then call this function.
                    //    In particular, we would like to avoid emit comments twice in following case:
                    //
                    //          var obj = {
                    //              id:
                    //                  /*comment*/ () => void
                    //          }
                    //
                    // 3. If the function is an argument in call expression, emitting of comments will be
                    //    taken care of in emit list of arguments inside of 'emitCallExpression'.
                    //
                    // 4. If the function is in an array literal, 'emitLinePreservingList' will take care
                    //    of leading comments.
                    emitLeadingComments(node);
                }
                emitStart(node);
                // For targeting below es6, emit functions-like declaration including arrow function using function keyword.
                // When targeting ES6, emit arrow function natively in ES6 by omitting function keyword and using fat arrow instead
                if (!shouldEmitAsArrowFunction(node)) {
                    if (isES6ExportedDeclaration(node)) {
                        write("export ");
                        if (node.flags & 512 /* Default */) {
                            write("default ");
                        }
                    }
                    write("function");
                    if (languageVersion >= 2 /* ES6 */ && node.asteriskToken) {
                        write("*");
                    }
                    write(" ");
                }
                if (shouldEmitFunctionName(node)) {
                    emitDeclarationName(node);
                }
                emitSignatureAndBody(node);
                if (modulekind !== ts.ModuleKind.ES6 && kind === 220 /* FunctionDeclaration */ && parent === currentSourceFile && node.name) {
                    emitExportMemberAssignments(node.name);
                }
                emitEnd(node);
                if (kind !== 147 /* MethodDeclaration */ &&
                    kind !== 146 /* MethodSignature */ &&
                    kind !== 180 /* ArrowFunction */) {
                    emitTrailingComments(node);
                }
            }
            function emitCaptureThisForNodeIfNecessary(node) {
                if (resolver.getNodeCheckFlags(node) & 4 /* CaptureThis */) {
                    writeLine();
                    emitStart(node);
                    write("var _this = this;");
                    emitEnd(node);
                }
            }
            function emitSignatureParameters(node) {
                increaseIndent();
                write("(");
                if (node) {
                    var parameters = node.parameters;
                    var skipCount = node.parameters.length && node.parameters[0].name.text === "this" ? 1 : 0;
                    var omitCount = languageVersion < 2 /* ES6 */ && ts.hasDeclaredRestParameter(node) ? 1 : 0;
                    emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false);
                }
                write(")");
                decreaseIndent();
            }
            function emitSignatureParametersForArrow(node) {
                // Check whether the parameter list needs parentheses and preserve no-parenthesis
                if (node.parameters.length === 1 && node.pos === node.parameters[0].pos) {
                    emit(node.parameters[0]);
                    return;
                }
                emitSignatureParameters(node);
            }
            function emitAsyncFunctionBodyForES6(node) {
                var promiseConstructor = ts.getEntityNameFromTypeNode(node.type);
                var isArrowFunction = node.kind === 180 /* 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.
                //
                // The emit for an async arrow without a lexical `arguments` binding might be:
                //
                //  // input
                //  let a = async (b) => { await b; }
                //
                //  // output
                //  let a = (b) => __awaiter(this, void 0, void 0, function* () {
                //      yield b;
                //  });
                //
                // The emit for an async arrow with a lexical `arguments` binding might be:
                //
                //  // input
                //  let a = async (b) => { await arguments[0]; }
                //
                //  // output
                //  let a = (b) => __awaiter(this, arguments, void 0, function* (arguments) {
                //      yield arguments[0];
                //  });
                //
                // The emit for an async function expression without a lexical `arguments` binding
                // might be:
                //
                //  // input
                //  let a = async function (b) {
                //      await b;
                //  }
                //
                //  // output
                //  let a = function (b) {
                //      return __awaiter(this, void 0, void 0, function* () {
                //          yield b;
                //      });
                //  }
                //
                // The emit for an async function expression with a lexical `arguments` binding
                // might be:
                //
                //  // input
                //  let a = async function (b) {
                //      await arguments[0];
                //  }
                //
                //  // output
                //  let a = function (b) {
                //      return __awaiter(this, arguments, void 0, function* (_arguments) {
                //          yield _arguments[0];
                //      });
                //  }
                //
                // The emit for an async function expression with a lexical `arguments` binding
                // and a return type annotation might be:
                //
                //  // input
                //  let a = async function (b): MyPromise<any> {
                //      await arguments[0];
                //  }
                //
                //  // output
                //  let a = function (b) {
                //      return __awaiter(this, arguments, MyPromise, function* (_arguments) {
                //          yield _arguments[0];
                //      });
                //  }
                //
                // If this is not an async arrow, emit the opening brace of the function body
                // and the start of the return statement.
                if (!isArrowFunction) {
                    write(" {");
                    increaseIndent();
                    writeLine();
                    if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                        writeLines("\nconst _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);");
                        writeLine();
                    }
                    else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                        write("const _super = name => super[name];");
                        writeLine();
                    }
                    write("return");
                }
                write(" __awaiter(this");
                if (hasLexicalArguments) {
                    write(", arguments, ");
                }
                else {
                    write(", void 0, ");
                }
                if (languageVersion >= 2 /* ES6 */ || !promiseConstructor) {
                    write("void 0");
                }
                else {
                    emitEntityNameAsExpression(promiseConstructor, /*useFallback*/ false);
                }
                // Emit the call to __awaiter.
                write(", function* ()");
                // Emit the signature and body for the inner generator function.
                emitFunctionBody(node);
                write(")");
                // If this is not an async arrow, emit the closing brace of the outer function body.
                if (!isArrowFunction) {
                    write(";");
                    decreaseIndent();
                    writeLine();
                    write("}");
                }
            }
            function emitFunctionBody(node) {
                if (!node.body) {
                    // There can be no body when there are parse errors.  Just emit an empty block
                    // in that case.
                    write(" { }");
                }
                else {
                    if (node.body.kind === 199 /* Block */) {
                        emitBlockFunctionBody(node, node.body);
                    }
                    else {
                        emitExpressionFunctionBody(node, node.body);
                    }
                }
            }
            function emitSignatureAndBody(node) {
                var saveConvertedLoopState = convertedLoopState;
                var saveTempFlags = tempFlags;
                var saveTempVariables = tempVariables;
                var saveTempParameters = tempParameters;
                convertedLoopState = undefined;
                tempFlags = 0;
                tempVariables = undefined;
                tempParameters = undefined;
                // When targeting ES6, emit arrow function natively in ES6
                if (shouldEmitAsArrowFunction(node)) {
                    emitSignatureParametersForArrow(node);
                    write(" =>");
                }
                else {
                    emitSignatureParameters(node);
                }
                var isAsync = ts.isAsyncFunctionLike(node);
                if (isAsync) {
                    emitAsyncFunctionBodyForES6(node);
                }
                else {
                    emitFunctionBody(node);
                }
                if (!isES6ExportedDeclaration(node)) {
                    emitExportMemberAssignment(node);
                }
                ts.Debug.assert(convertedLoopState === undefined);
                convertedLoopState = saveConvertedLoopState;
                tempFlags = saveTempFlags;
                tempVariables = saveTempVariables;
                tempParameters = saveTempParameters;
            }
            // Returns true if any preamble code was emitted.
            function emitFunctionBodyPreamble(node) {
                emitCaptureThisForNodeIfNecessary(node);
                emitDefaultValueAssignments(node);
                emitRestParameter(node);
            }
            function emitExpressionFunctionBody(node, body) {
                if (languageVersion < 2 /* ES6 */ || node.flags & 256 /* Async */) {
                    emitDownLevelExpressionFunctionBody(node, body);
                    return;
                }
                // For es6 and higher we can emit the expression as is.  However, in the case
                // where the expression might end up looking like a block when emitted, we'll
                // also wrap it in parentheses first.  For example if you have: a => <foo>{}
                // then we need to generate: a => ({})
                write(" ");
                // Unwrap all type assertions.
                var current = body;
                while (current.kind === 177 /* TypeAssertionExpression */) {
                    current = current.expression;
                }
                emitParenthesizedIf(body, current.kind === 171 /* ObjectLiteralExpression */);
            }
            function emitDownLevelExpressionFunctionBody(node, body) {
                write(" {");
                increaseIndent();
                var outPos = writer.getTextPos();
                emitDetachedCommentsAndUpdateCommentsInfo(node.body);
                emitFunctionBodyPreamble(node);
                var preambleEmitted = writer.getTextPos() !== outPos;
                decreaseIndent();
                // If we didn't have to emit any preamble code, then attempt to keep the arrow
                // function on one line.
                if (!preambleEmitted && nodeStartPositionsAreOnSameLine(node, body)) {
                    write(" ");
                    emitStart(body);
                    write("return ");
                    emit(body);
                    emitEnd(body);
                    write(";");
                    emitTempDeclarations(/*newLine*/ false);
                    write(" ");
                }
                else {
                    increaseIndent();
                    writeLine();
                    emitLeadingComments(node.body);
                    emitStart(body);
                    write("return ");
                    emit(body);
                    emitEnd(body);
                    write(";");
                    emitTrailingComments(node.body);
                    emitTempDeclarations(/*newLine*/ true);
                    decreaseIndent();
                    writeLine();
                }
                emitStart(node.body);
                write("}");
                emitEnd(node.body);
            }
            function emitBlockFunctionBody(node, body) {
                write(" {");
                var initialTextPos = writer.getTextPos();
                increaseIndent();
                emitDetachedCommentsAndUpdateCommentsInfo(body.statements);
                // Emit all the directive prologues (like "use strict").  These have to come before
                // any other preamble code we write (like parameter initializers).
                var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true);
                emitFunctionBodyPreamble(node);
                decreaseIndent();
                var preambleEmitted = writer.getTextPos() !== initialTextPos;
                if (!preambleEmitted && nodeEndIsOnSameLineAsNodeStart(body, body)) {
                    for (var _a = 0, _b = body.statements; _a < _b.length; _a++) {
                        var statement = _b[_a];
                        write(" ");
                        emit(statement);
                    }
                    emitTempDeclarations(/*newLine*/ false);
                    write(" ");
                    emitLeadingCommentsOfPosition(body.statements.end);
                }
                else {
                    increaseIndent();
                    emitLinesStartingAt(body.statements, startIndex);
                    emitTempDeclarations(/*newLine*/ true);
                    writeLine();
                    emitLeadingCommentsOfPosition(body.statements.end);
                    decreaseIndent();
                }
                emitToken(16 /* CloseBraceToken */, body.statements.end);
            }
            /**
             * Return the statement at a given index if it is a super-call statement
             * @param ctor a constructor declaration
             * @param index an index to constructor's body to check
             */
            function getSuperCallAtGivenIndex(ctor, index) {
                if (!ctor.body) {
                    return undefined;
                }
                var statements = ctor.body.statements;
                if (!statements || index >= statements.length) {
                    return undefined;
                }
                var statement = statements[index];
                if (statement.kind === 202 /* ExpressionStatement */) {
                    return ts.isSuperCallExpression(statement.expression) ? statement : undefined;
                }
            }
            function emitParameterPropertyAssignments(node) {
                ts.forEach(node.parameters, function (param) {
                    if (param.flags & 92 /* ParameterPropertyModifier */) {
                        writeLine();
                        emitStart(param);
                        emitStart(param.name);
                        write("this.");
                        emitNodeWithoutSourceMap(param.name);
                        emitEnd(param.name);
                        write(" = ");
                        emit(param.name);
                        write(";");
                        emitEnd(param);
                    }
                });
            }
            function emitMemberAccessForPropertyName(memberName) {
                // This does not emit source map because it is emitted by caller as caller
                // is aware how the property name changes to the property access
                // eg. public x = 10; becomes this.x and static x = 10 becomes className.x
                if (memberName.kind === 9 /* StringLiteral */ || memberName.kind === 8 /* NumericLiteral */) {
                    write("[");
                    emitNodeWithCommentsAndWithoutSourcemap(memberName);
                    write("]");
                }
                else if (memberName.kind === 140 /* ComputedPropertyName */) {
                    emitComputedPropertyName(memberName);
                }
                else {
                    write(".");
                    emitNodeWithCommentsAndWithoutSourcemap(memberName);
                }
            }
            function getInitializedProperties(node, isStatic) {
                var properties = [];
                for (var _a = 0, _b = node.members; _a < _b.length; _a++) {
                    var member = _b[_a];
                    if (member.kind === 145 /* PropertyDeclaration */ && isStatic === ((member.flags & 32 /* Static */) !== 0) && member.initializer) {
                        properties.push(member);
                    }
                }
                return properties;
            }
            function emitPropertyDeclarations(node, properties) {
                for (var _a = 0, properties_6 = properties; _a < properties_6.length; _a++) {
                    var property = properties_6[_a];
                    emitPropertyDeclaration(node, property);
                }
            }
            function emitPropertyDeclaration(node, property, receiver, isExpression) {
                writeLine();
                emitLeadingComments(property);
                emitStart(property);
                emitStart(property.name);
                if (receiver) {
                    write(receiver);
                }
                else {
                    if (property.flags & 32 /* Static */) {
                        emitDeclarationName(node);
                    }
                    else {
                        write("this");
                    }
                }
                emitMemberAccessForPropertyName(property.name);
                emitEnd(property.name);
                write(" = ");
                emit(property.initializer);
                if (!isExpression) {
                    write(";");
                }
                emitEnd(property);
                emitTrailingComments(property);
            }
            function emitMemberFunctionsForES5AndLower(node) {
                ts.forEach(node.members, function (member) {
                    if (member.kind === 198 /* SemicolonClassElement */) {
                        writeLine();
                        write(";");
                    }
                    else if (member.kind === 147 /* MethodDeclaration */ || node.kind === 146 /* MethodSignature */) {
                        if (!member.body) {
                            return emitCommentsOnNotEmittedNode(member);
                        }
                        writeLine();
                        emitLeadingComments(member);
                        emitStart(member);
                        emitStart(member.name);
                        emitClassMemberPrefix(node, member);
                        emitMemberAccessForPropertyName(member.name);
                        emitEnd(member.name);
                        write(" = ");
                        emitFunctionDeclaration(member);
                        emitEnd(member);
                        write(";");
                        emitTrailingComments(member);
                    }
                    else if (member.kind === 149 /* GetAccessor */ || member.kind === 150 /* SetAccessor */) {
                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
                        if (member === accessors.firstAccessor) {
                            writeLine();
                            emitStart(member);
                            write("Object.defineProperty(");
                            emitStart(member.name);
                            emitClassMemberPrefix(node, member);
                            write(", ");
                            emitExpressionForPropertyName(member.name);
                            emitEnd(member.name);
                            write(", {");
                            increaseIndent();
                            if (accessors.getAccessor) {
                                writeLine();
                                emitLeadingComments(accessors.getAccessor);
                                write("get: ");
                                emitStart(accessors.getAccessor);
                                write("function ");
                                emitSignatureAndBody(accessors.getAccessor);
                                emitEnd(accessors.getAccessor);
                                emitTrailingComments(accessors.getAccessor);
                                write(",");
                            }
                            if (accessors.setAccessor) {
                                writeLine();
                                emitLeadingComments(accessors.setAccessor);
                                write("set: ");
                                emitStart(accessors.setAccessor);
                                write("function ");
                                emitSignatureAndBody(accessors.setAccessor);
                                emitEnd(accessors.setAccessor);
                                emitTrailingComments(accessors.setAccessor);
                                write(",");
                            }
                            writeLine();
                            write("enumerable: true,");
                            writeLine();
                            write("configurable: true");
                            decreaseIndent();
                            writeLine();
                            write("});");
                            emitEnd(member);
                        }
                    }
                });
            }
            function emitMemberFunctionsForES6AndHigher(node) {
                for (var _a = 0, _b = node.members; _a < _b.length; _a++) {
                    var member = _b[_a];
                    if ((member.kind === 147 /* MethodDeclaration */ || node.kind === 146 /* MethodSignature */) && !member.body) {
                        emitCommentsOnNotEmittedNode(member);
                    }
                    else if (member.kind === 147 /* MethodDeclaration */ ||
                        member.kind === 149 /* GetAccessor */ ||
                        member.kind === 150 /* SetAccessor */) {
                        writeLine();
                        emitLeadingComments(member);
                        emitStart(member);
                        if (member.flags & 32 /* Static */) {
                            write("static ");
                        }
                        if (member.kind === 149 /* GetAccessor */) {
                            write("get ");
                        }
                        else if (member.kind === 150 /* SetAccessor */) {
                            write("set ");
                        }
                        if (member.asteriskToken) {
                            write("*");
                        }
                        emit(member.name);
                        emitSignatureAndBody(member);
                        emitEnd(member);
                        emitTrailingComments(member);
                    }
                    else if (member.kind === 198 /* SemicolonClassElement */) {
                        writeLine();
                        write(";");
                    }
                }
            }
            function emitConstructor(node, baseTypeElement) {
                var saveConvertedLoopState = convertedLoopState;
                var saveTempFlags = tempFlags;
                var saveTempVariables = tempVariables;
                var saveTempParameters = tempParameters;
                convertedLoopState = undefined;
                tempFlags = 0;
                tempVariables = undefined;
                tempParameters = undefined;
                emitConstructorWorker(node, baseTypeElement);
                ts.Debug.assert(convertedLoopState === undefined);
                convertedLoopState = saveConvertedLoopState;
                tempFlags = saveTempFlags;
                tempVariables = saveTempVariables;
                tempParameters = saveTempParameters;
            }
            function emitConstructorWorker(node, baseTypeElement) {
                // Check if we have property assignment inside class declaration.
                // If there is property assignment, we need to emit constructor whether users define it or not
                // If there is no property assignment, we can omit constructor if users do not define it
                var hasInstancePropertyWithInitializer = false;
                // Emit the constructor overload pinned comments
                ts.forEach(node.members, function (member) {
                    if (member.kind === 148 /* Constructor */ && !member.body) {
                        emitCommentsOnNotEmittedNode(member);
                    }
                    // Check if there is any non-static property assignment
                    if (member.kind === 145 /* PropertyDeclaration */ && member.initializer && (member.flags & 32 /* Static */) === 0) {
                        hasInstancePropertyWithInitializer = true;
                    }
                });
                var ctor = ts.getFirstConstructorWithBody(node);
                // For target ES6 and above, if there is no user-defined constructor and there is no property assignment
                // do not emit constructor in class declaration.
                if (languageVersion >= 2 /* ES6 */ && !ctor && !hasInstancePropertyWithInitializer) {
                    return;
                }
                if (ctor) {
                    emitLeadingComments(ctor);
                }
                emitStart(ctor || node);
                if (languageVersion < 2 /* ES6 */) {
                    write("function ");
                    emitDeclarationName(node);
                    emitSignatureParameters(ctor);
                }
                else {
                    write("constructor");
                    if (ctor) {
                        emitSignatureParameters(ctor);
                    }
                    else {
                        // Based on EcmaScript6 section 14.5.14: Runtime Semantics: ClassDefinitionEvaluation.
                        // If constructor is empty, then,
                        //      If ClassHeritageopt is present, then
                        //          Let constructor be the result of parsing the String "constructor(... args){ super (...args);}" using the syntactic grammar with the goal symbol MethodDefinition.
                        //      Else,
                        //          Let constructor be the result of parsing the String "constructor( ){ }" using the syntactic grammar with the goal symbol MethodDefinition
                        if (baseTypeElement) {
                            write("(...args)");
                        }
                        else {
                            write("()");
                        }
                    }
                }
                var startIndex = 0;
                write(" {");
                increaseIndent();
                if (ctor) {
                    // Emit all the directive prologues (like "use strict").  These have to come before
                    // any other preamble code we write (like parameter initializers).
                    startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true);
                    emitDetachedCommentsAndUpdateCommentsInfo(ctor.body.statements);
                }
                emitCaptureThisForNodeIfNecessary(node);
                var superCall;
                if (ctor) {
                    emitDefaultValueAssignments(ctor);
                    emitRestParameter(ctor);
                    if (baseTypeElement) {
                        superCall = getSuperCallAtGivenIndex(ctor, startIndex);
                        if (superCall) {
                            writeLine();
                            emit(superCall);
                        }
                    }
                    emitParameterPropertyAssignments(ctor);
                }
                else {
                    if (baseTypeElement) {
                        writeLine();
                        emitStart(baseTypeElement);
                        if (languageVersion < 2 /* ES6 */) {
                            write("_super.apply(this, arguments);");
                        }
                        else {
                            write("super(...args);");
                        }
                        emitEnd(baseTypeElement);
                    }
                }
                emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ false));
                if (ctor) {
                    var statements = ctor.body.statements;
                    if (superCall) {
                        statements = statements.slice(1);
                    }
                    emitLinesStartingAt(statements, startIndex);
                }
                emitTempDeclarations(/*newLine*/ true);
                writeLine();
                if (ctor) {
                    emitLeadingCommentsOfPosition(ctor.body.statements.end);
                }
                decreaseIndent();
                emitToken(16 /* CloseBraceToken */, ctor ? ctor.body.statements.end : node.members.end);
                emitEnd(ctor || node);
                if (ctor) {
                    emitTrailingComments(ctor);
                }
            }
            function emitClassExpression(node) {
                return emitClassLikeDeclaration(node);
            }
            function emitClassDeclaration(node) {
                return emitClassLikeDeclaration(node);
            }
            function emitClassLikeDeclaration(node) {
                if (languageVersion < 2 /* ES6 */) {
                    emitClassLikeDeclarationBelowES6(node);
                }
                else {
                    emitClassLikeDeclarationForES6AndHigher(node);
                }
                if (modulekind !== ts.ModuleKind.ES6 && node.parent === currentSourceFile && node.name) {
                    emitExportMemberAssignments(node.name);
                }
            }
            function emitClassLikeDeclarationForES6AndHigher(node) {
                var decoratedClassAlias;
                var isHoistedDeclarationInSystemModule = shouldHoistDeclarationInSystemJsModule(node);
                var isDecorated = ts.nodeIsDecorated(node);
                var rewriteAsClassExpression = isDecorated || isHoistedDeclarationInSystemModule;
                if (node.kind === 221 /* ClassDeclaration */) {
                    if (rewriteAsClassExpression) {
                        // 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:
                        //
                        //  TypeScript                      | Javascript
                        //  --------------------------------|------------------------------------
                        //  @dec                            | let C = class C {
                        //  class C {                       | }
                        //  }                               | C = __decorate([dec], C);
                        //  --------------------------------|------------------------------------
                        //  @dec                            | export let C = class C {
                        //  export class C {                | }
                        //  }                               | C = __decorate([dec], C);
                        //  ---------------------------------------------------------------------
                        //  [Example 1]
                        //
                        // 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:
                        //
                        //  TypeScript                      | Javascript
                        //  --------------------------------|------------------------------------
                        //  @dec                            | let C_1 = class C {
                        //  class C {                       |   static x() { return C_1.y; }
                        //    static x() { return C.y; }    | }
                        //    static y = 1;                 | let C = C_1;
                        //  }                               | C.y = 1;
                        //                                  | C = C_1 = __decorate([dec], C);
                        //  --------------------------------|------------------------------------
                        //  @dec                            | let C_1 = class C {
                        //  export class C {                |   static x() { return C_1.y; }
                        //    static x() { return C.y; }    | }
                        //    static y = 1;                 | export let C = C_1;
                        //  }                               | C.y = 1;
                        //                                  | C = C_1 = __decorate([dec], C);
                        //  ---------------------------------------------------------------------
                        //  [Example 2]
                        //
                        // If a class declaration is the default export of a module, we instead emit
                        // the export after the decorated declaration:
                        //
                        //  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 = __decorate([dec], C);
                        //                                  | export default C;
                        //  ---------------------------------------------------------------------
                        //  [Example 3]
                        //
                        // 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:
                        //
                        //  TypeScript                      | Javascript
                        //  --------------------------------|------------------------------------
                        //  @dec                            | let C_1 = class C {
                        //  export default class C {        |   static x() { return C_1.y; }
                        //    static x() { return C.y; }    | };
                        //    static y = 1;                 | let C = C_1;
                        //  }                               | C.y = 1;
                        //                                  | C = C_1 = __decorate([dec], C);
                        //                                  | export default C;
                        //  ---------------------------------------------------------------------
                        //  [Example 4]
                        //
                        // NOTE: we reuse the same rewriting logic for cases when targeting ES6 and module kind is System.
                        // Because of hoisting top level class declaration need to be emitted as class expressions.
                        // Double bind case is only required if node is decorated.
                        if (isDecorated && resolver.getNodeCheckFlags(node) & 524288 /* ClassWithBodyScopedClassBinding */) {
                            decoratedClassAlias = ts.unescapeIdentifier(makeUniqueName(node.name ? node.name.text : "default"));
                            decoratedClassAliases[ts.getNodeId(node)] = decoratedClassAlias;
                        }
                        if (isES6ExportedDeclaration(node) && !(node.flags & 512 /* Default */) && decoratedClassAlias === undefined) {
                            write("export ");
                        }
                        if (!isHoistedDeclarationInSystemModule) {
                            write("let ");
                        }
                        if (decoratedClassAlias !== undefined) {
                            write("" + decoratedClassAlias);
                        }
                        else {
                            emitDeclarationName(node);
                        }
                        write(" = ");
                    }
                    else if (isES6ExportedDeclaration(node)) {
                        write("export ");
                        if (node.flags & 512 /* Default */) {
                            write("default ");
                        }
                    }
                }
                // If the class has static properties, and it's a class expression, then we'll need
                // to specialize the emit a bit.  for a class expression of the form:
                //
                //      class C { static a = 1; static b = 2; ... }
                //
                // We'll emit:
                //
                //      (_temp = class C { ... }, _temp.a = 1, _temp.b = 2, _temp)
                //
                // This keeps the expression as an expression, while ensuring that the static parts
                // of it have been initialized by the time it is used.
                var staticProperties = getInitializedProperties(node, /*isStatic*/ true);
                var isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === 192 /* ClassExpression */;
                var generatedName;
                if (isClassExpressionWithStaticProperties) {
                    generatedName = getGeneratedNameForNode(node.name);
                    var synthesizedNode = ts.createSynthesizedNode(69 /* Identifier */);
                    synthesizedNode.text = generatedName;
                    recordTempDeclaration(synthesizedNode);
                    write("(");
                    increaseIndent();
                    emit(synthesizedNode);
                    write(" = ");
                }
                write("class");
                // emit name if
                // - node has a name
                // - this is default export with static initializers
                if (node.name || (node.flags & 512 /* Default */ && (staticProperties.length > 0 || modulekind !== ts.ModuleKind.ES6) && !rewriteAsClassExpression)) {
                    write(" ");
                    emitDeclarationName(node);
                }
                var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
                if (baseTypeNode) {
                    write(" extends ");
                    emit(baseTypeNode.expression);
                }
                write(" {");
                increaseIndent();
                writeLine();
                emitConstructor(node, baseTypeNode);
                emitMemberFunctionsForES6AndHigher(node);
                decreaseIndent();
                writeLine();
                emitToken(16 /* CloseBraceToken */, node.members.end);
                if (rewriteAsClassExpression) {
                    if (decoratedClassAlias !== undefined) {
                        write(";");
                        writeLine();
                        if (isES6ExportedDeclaration(node) && !(node.flags & 512 /* Default */)) {
                            write("export ");
                        }
                        write("let ");
                        emitDeclarationName(node);
                        write(" = " + decoratedClassAlias);
                    }
                    decoratedClassAliases[ts.getNodeId(node)] = undefined;
                    write(";");
                }
                // Emit static property assignment. Because classDeclaration is lexically evaluated,
                // it is safe to emit static property assignment after classDeclaration
                // From ES6 specification:
                //      HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
                //                                  a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
                if (isClassExpressionWithStaticProperties) {
                    for (var _a = 0, staticProperties_1 = staticProperties; _a < staticProperties_1.length; _a++) {
                        var property = staticProperties_1[_a];
                        write(",");
                        writeLine();
                        emitPropertyDeclaration(node, property, /*receiver*/ generatedName, /*isExpression*/ true);
                    }
                    write(",");
                    writeLine();
                    write(generatedName);
                    decreaseIndent();
                    write(")");
                }
                else {
                    writeLine();
                    emitPropertyDeclarations(node, staticProperties);
                    emitDecoratorsOfClass(node, decoratedClassAlias);
                }
                if (!(node.flags & 1 /* Export */)) {
                    return;
                }
                if (modulekind !== ts.ModuleKind.ES6) {
                    emitExportMemberAssignment(node);
                }
                else {
                    // If this is an exported class, but not on the top level (i.e. on an internal
                    // module), export it
                    if (node.flags & 512 /* Default */) {
                        // if this is a top level default export of decorated class, write the export after the declaration.
                        if (isDecorated) {
                            writeLine();
                            write("export default ");
                            emitDeclarationName(node);
                            write(";");
                        }
                    }
                    else if (node.parent.kind !== 256 /* SourceFile */) {
                        writeLine();
                        emitStart(node);
                        emitModuleMemberName(node);
                        write(" = ");
                        emitDeclarationName(node);
                        emitEnd(node);
                        write(";");
                    }
                }
            }
            function emitClassLikeDeclarationBelowES6(node) {
                var isES6ExportedClass = isES6ExportedDeclaration(node);
                if (node.kind === 221 /* ClassDeclaration */) {
                    if (isES6ExportedClass && !(node.flags & 512 /* Default */)) {
                        write("export ");
                    }
                    // source file level classes in system modules are hoisted so 'var's for them are already defined
                    if (!shouldHoistDeclarationInSystemJsModule(node)) {
                        write("var ");
                    }
                    emitDeclarationName(node);
                    write(" = ");
                }
                write("(function (");
                var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
                if (baseTypeNode) {
                    write("_super");
                }
                write(") {");
                var saveTempFlags = tempFlags;
                var saveTempVariables = tempVariables;
                var saveTempParameters = tempParameters;
                var saveComputedPropertyNamesToGeneratedNames = computedPropertyNamesToGeneratedNames;
                var saveConvertedLoopState = convertedLoopState;
                convertedLoopState = undefined;
                tempFlags = 0;
                tempVariables = undefined;
                tempParameters = undefined;
                computedPropertyNamesToGeneratedNames = undefined;
                increaseIndent();
                if (baseTypeNode) {
                    writeLine();
                    emitStart(baseTypeNode);
                    write("__extends(");
                    emitDeclarationName(node);
                    write(", _super);");
                    emitEnd(baseTypeNode);
                }
                writeLine();
                emitConstructor(node, baseTypeNode);
                emitMemberFunctionsForES5AndLower(node);
                emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ true));
                writeLine();
                emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
                writeLine();
                emitToken(16 /* CloseBraceToken */, node.members.end, function () {
                    write("return ");
                    emitDeclarationName(node);
                });
                write(";");
                emitTempDeclarations(/*newLine*/ true);
                ts.Debug.assert(convertedLoopState === undefined);
                convertedLoopState = saveConvertedLoopState;
                tempFlags = saveTempFlags;
                tempVariables = saveTempVariables;
                tempParameters = saveTempParameters;
                computedPropertyNamesToGeneratedNames = saveComputedPropertyNamesToGeneratedNames;
                decreaseIndent();
                writeLine();
                emitToken(16 /* CloseBraceToken */, node.members.end);
                emitStart(node);
                write("(");
                if (baseTypeNode) {
                    emit(baseTypeNode.expression);
                }
                write("))");
                if (node.kind === 221 /* ClassDeclaration */) {
                    write(";");
                }
                emitEnd(node);
                if (node.kind === 221 /* ClassDeclaration */ && !isES6ExportedClass) {
                    emitExportMemberAssignment(node);
                }
                else if (isES6ExportedClass && (node.flags & 512 /* Default */)) {
                    writeLine();
                    write("export default ");
                    emitDeclarationName(node);
                    write(";");
                }
            }
            function emitClassMemberPrefix(node, member) {
                emitDeclarationName(node);
                if (!(member.flags & 32 /* Static */)) {
                    write(".prototype");
                }
            }
            function emitDecoratorsOfClass(node, decoratedClassAlias) {
                emitDecoratorsOfMembers(node, /*staticFlag*/ 0);
                emitDecoratorsOfMembers(node, 32 /* Static */);
                emitDecoratorsOfConstructor(node, decoratedClassAlias);
            }
            function emitDecoratorsOfConstructor(node, decoratedClassAlias) {
                var decorators = node.decorators;
                var constructor = ts.getFirstConstructorWithBody(node);
                var firstParameterDecorator = constructor && ts.forEach(constructor.parameters, function (parameter) { return parameter.decorators; });
                // skip decoration of the constructor if neither it nor its parameters are decorated
                if (!decorators && !firstParameterDecorator) {
                    return;
                }
                // Emit the call to __decorate. Given the class:
                //
                //   @dec
                //   class C {
                //   }
                //
                // The emit for the class is:
                //
                //   C = __decorate([dec], C);
                //
                writeLine();
                emitStart(node.decorators || firstParameterDecorator);
                emitDeclarationName(node);
                if (decoratedClassAlias !== undefined) {
                    write(" = " + decoratedClassAlias);
                }
                write(" = __decorate([");
                increaseIndent();
                writeLine();
                var decoratorCount = decorators ? decorators.length : 0;
                var argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, function (decorator) { return emit(decorator.expression); });
                if (firstParameterDecorator) {
                    argumentsWritten += emitDecoratorsOfParameters(constructor, /*leadingComma*/ argumentsWritten > 0);
                }
                emitSerializedTypeMetadata(node, /*leadingComma*/ argumentsWritten >= 0);
                decreaseIndent();
                writeLine();
                write("], ");
                emitDeclarationName(node);
                write(")");
                emitEnd(node.decorators || firstParameterDecorator);
                write(";");
                writeLine();
            }
            function emitDecoratorsOfMembers(node, staticFlag) {
                for (var _a = 0, _b = node.members; _a < _b.length; _a++) {
                    var member = _b[_a];
                    // only emit members in the correct group
                    if ((member.flags & 32 /* Static */) !== staticFlag) {
                        continue;
                    }
                    // skip members that cannot be decorated (such as the constructor)
                    if (!ts.nodeCanBeDecorated(member)) {
                        continue;
                    }
                    // skip an accessor declaration if it is not the first accessor
                    var decorators = void 0;
                    var functionLikeMember = void 0;
                    if (ts.isAccessor(member)) {
                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
                        if (member !== accessors.firstAccessor) {
                            continue;
                        }
                        // get the decorators from the first accessor with decorators
                        decorators = accessors.firstAccessor.decorators;
                        if (!decorators && accessors.secondAccessor) {
                            decorators = accessors.secondAccessor.decorators;
                        }
                        // we only decorate parameters of the set accessor
                        functionLikeMember = accessors.setAccessor;
                    }
                    else {
                        decorators = member.decorators;
                        // we only decorate the parameters here if this is a method
                        if (member.kind === 147 /* MethodDeclaration */) {
                            functionLikeMember = member;
                        }
                    }
                    var firstParameterDecorator = functionLikeMember && ts.forEach(functionLikeMember.parameters, function (parameter) { return parameter.decorators; });
                    // skip a member if it or any of its parameters are not decorated
                    if (!decorators && !firstParameterDecorator) {
                        continue;
                    }
                    // 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", undefined);
                    //
                    // The emit for an accessor is:
                    //
                    //   __decorate([
                    //       dec
                    //   ], C.prototype, "accessor", undefined);
                    //
                    // The emit for a property is:
                    //
                    //   __decorate([
                    //       dec
                    //   ], C.prototype, "prop");
                    //
                    writeLine();
                    emitStart(decorators || firstParameterDecorator);
                    write("__decorate([");
                    increaseIndent();
                    writeLine();
                    var decoratorCount = decorators ? decorators.length : 0;
                    var argumentsWritten = emitList(decorators, 0, decoratorCount, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ false, /*noTrailingNewLine*/ true, function (decorator) { return emit(decorator.expression); });
                    if (firstParameterDecorator) {
                        argumentsWritten += emitDecoratorsOfParameters(functionLikeMember, argumentsWritten > 0);
                    }
                    emitSerializedTypeMetadata(member, argumentsWritten > 0);
                    decreaseIndent();
                    writeLine();
                    write("], ");
                    emitClassMemberPrefix(node, member);
                    write(", ");
                    emitExpressionForPropertyName(member.name);
                    if (languageVersion > 0 /* ES3 */) {
                        if (member.kind !== 145 /* PropertyDeclaration */) {
                            // 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.
                            write(", null");
                        }
                        else {
                            // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it
                            // should not invoke `Object.getOwnPropertyDescriptor`.
                            write(", void 0");
                        }
                    }
                    write(")");
                    emitEnd(decorators || firstParameterDecorator);
                    write(";");
                    writeLine();
                }
            }
            function emitDecoratorsOfParameters(node, leadingComma) {
                var argumentsWritten = 0;
                if (node) {
                    var parameterIndex_1 = 0;
                    for (var _a = 0, _b = node.parameters; _a < _b.length; _a++) {
                        var parameter = _b[_a];
                        if (ts.nodeIsDecorated(parameter)) {
                            var decorators = parameter.decorators;
                            argumentsWritten += emitList(decorators, 0, decorators.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ leadingComma, /*noTrailingNewLine*/ true, function (decorator) {
                                write("__param(" + parameterIndex_1 + ", ");
                                emit(decorator.expression);
                                write(")");
                            });
                            leadingComma = true;
                        }
                        parameterIndex_1++;
                    }
                }
                return argumentsWritten;
            }
            function shouldEmitTypeMetadata(node) {
                // This method determines whether to emit the "design:type" metadata based on the node's kind.
                // The caller should have already tested whether the node has decorators and whether the emitDecoratorMetadata
                // compiler option is set.
                switch (node.kind) {
                    case 147 /* MethodDeclaration */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 145 /* PropertyDeclaration */:
                        return true;
                }
                return false;
            }
            function shouldEmitReturnTypeMetadata(node) {
                // This method determines whether to emit the "design:returntype" metadata based on the node's kind.
                // The caller should have already tested whether the node has decorators and whether the emitDecoratorMetadata
                // compiler option is set.
                switch (node.kind) {
                    case 147 /* MethodDeclaration */:
                        return true;
                }
                return false;
            }
            function shouldEmitParamTypesMetadata(node) {
                // This method determines whether to emit the "design:paramtypes" metadata based on the node's kind.
                // The caller should have already tested whether the node has decorators and whether the emitDecoratorMetadata
                // compiler option is set.
                switch (node.kind) {
                    case 221 /* ClassDeclaration */:
                    case 147 /* MethodDeclaration */:
                    case 150 /* SetAccessor */:
                        return true;
                }
                return false;
            }
            /** Serializes the type of a declaration to an appropriate JS constructor value. Used by the __metadata decorator for a class member. */
            function emitSerializedTypeOfNode(node) {
                // serialization of the type of a declaration uses the following rules:
                //
                // * The serialized type of a ClassDeclaration is "Function"
                // * The serialized type of a ParameterDeclaration is the serialized type of its type annotation.
                // * The serialized type of a PropertyDeclaration is the serialized type of its type annotation.
                // * The serialized type of an AccessorDeclaration is the serialized type of the return type annotation of its getter or parameter type annotation of its setter.
                // * The serialized type of any other FunctionLikeDeclaration is "Function".
                // * The serialized type of any other node is "void 0".
                //
                // For rules on serializing type annotations, see `serializeTypeNode`.
                switch (node.kind) {
                    case 221 /* ClassDeclaration */:
                        write("Function");
                        return;
                    case 145 /* PropertyDeclaration */:
                        emitSerializedTypeNode(node.type);
                        return;
                    case 142 /* Parameter */:
                        emitSerializedTypeNode(node.type);
                        return;
                    case 149 /* GetAccessor */:
                        emitSerializedTypeNode(node.type);
                        return;
                    case 150 /* SetAccessor */:
                        emitSerializedTypeNode(ts.getSetAccessorTypeAnnotationNode(node));
                        return;
                }
                if (ts.isFunctionLike(node)) {
                    write("Function");
                    return;
                }
                write("void 0");
            }
            function emitSerializedTypeNode(node) {
                if (node) {
                    switch (node.kind) {
                        case 103 /* VoidKeyword */:
                            write("void 0");
                            return;
                        case 164 /* ParenthesizedType */:
                            emitSerializedTypeNode(node.type);
                            return;
                        case 156 /* FunctionType */:
                        case 157 /* ConstructorType */:
                            write("Function");
                            return;
                        case 160 /* ArrayType */:
                        case 161 /* TupleType */:
                            write("Array");
                            return;
                        case 154 /* TypePredicate */:
                        case 120 /* BooleanKeyword */:
                            write("Boolean");
                            return;
                        case 132 /* StringKeyword */:
                        case 166 /* StringLiteralType */:
                            write("String");
                            return;
                        case 130 /* NumberKeyword */:
                            write("Number");
                            return;
                        case 133 /* SymbolKeyword */:
                            write("Symbol");
                            return;
                        case 155 /* TypeReference */:
                            emitSerializedTypeReferenceNode(node);
                            return;
                        case 158 /* TypeQuery */:
                        case 159 /* TypeLiteral */:
                        case 162 /* UnionType */:
                        case 163 /* IntersectionType */:
                        case 117 /* AnyKeyword */:
                        case 165 /* ThisType */:
                            break;
                        default:
                            ts.Debug.fail("Cannot serialize unexpected type node.");
                            break;
                    }
                }
                write("Object");
            }
            /** Serializes a TypeReferenceNode to an appropriate JS constructor value. Used by the __metadata decorator. */
            function emitSerializedTypeReferenceNode(node) {
                var location = node.parent;
                while (ts.isDeclaration(location) || ts.isTypeNode(location)) {
                    location = location.parent;
                }
                // Clone the type name and parent it to a location outside of the current declaration.
                var typeName = ts.cloneEntityName(node.typeName, location);
                var result = resolver.getTypeReferenceSerializationKind(typeName);
                switch (result) {
                    case ts.TypeReferenceSerializationKind.Unknown:
                        var temp = createAndRecordTempVariable(0 /* Auto */);
                        write("(typeof (");
                        emitNodeWithoutSourceMap(temp);
                        write(" = ");
                        emitEntityNameAsExpression(typeName, /*useFallback*/ true);
                        write(") === 'function' && ");
                        emitNodeWithoutSourceMap(temp);
                        write(") || Object");
                        break;
                    case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
                        emitEntityNameAsExpression(typeName, /*useFallback*/ false);
                        break;
                    case ts.TypeReferenceSerializationKind.VoidType:
                        write("void 0");
                        break;
                    case ts.TypeReferenceSerializationKind.BooleanType:
                        write("Boolean");
                        break;
                    case ts.TypeReferenceSerializationKind.NumberLikeType:
                        write("Number");
                        break;
                    case ts.TypeReferenceSerializationKind.StringLikeType:
                        write("String");
                        break;
                    case ts.TypeReferenceSerializationKind.ArrayLikeType:
                        write("Array");
                        break;
                    case ts.TypeReferenceSerializationKind.ESSymbolType:
                        if (languageVersion < 2 /* ES6 */) {
                            write("typeof Symbol === 'function' ? Symbol : Object");
                        }
                        else {
                            write("Symbol");
                        }
                        break;
                    case ts.TypeReferenceSerializationKind.TypeWithCallSignature:
                        write("Function");
                        break;
                    case ts.TypeReferenceSerializationKind.ObjectType:
                        write("Object");
                        break;
                }
            }
            /** Serializes the parameter types of a function or the constructor of a class. Used by the __metadata decorator for a method or set accessor. */
            function emitSerializedParameterTypesOfNode(node) {
                // serialization of parameter types uses the following rules:
                //
                // * If the declaration is a class, the parameters of the first constructor with a body are used.
                // * If the declaration is function-like and has a body, the parameters of the function are used.
                //
                // For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`.
                if (node) {
                    var valueDeclaration = void 0;
                    if (node.kind === 221 /* ClassDeclaration */) {
                        valueDeclaration = ts.getFirstConstructorWithBody(node);
                    }
                    else if (ts.isFunctionLike(node) && ts.nodeIsPresent(node.body)) {
                        valueDeclaration = node;
                    }
                    if (valueDeclaration) {
                        var parameters = valueDeclaration.parameters;
                        var parameterCount = parameters.length;
                        if (parameterCount > 0) {
                            for (var i = 0; i < parameterCount; i++) {
                                if (i > 0) {
                                    write(", ");
                                }
                                if (parameters[i].dotDotDotToken) {
                                    var parameterType = parameters[i].type;
                                    if (parameterType && parameterType.kind === 160 /* ArrayType */) {
                                        parameterType = parameterType.elementType;
                                    }
                                    else if (parameterType && parameterType.kind === 155 /* TypeReference */ && parameterType.typeArguments && parameterType.typeArguments.length === 1) {
                                        parameterType = parameterType.typeArguments[0];
                                    }
                                    else {
                                        parameterType = undefined;
                                    }
                                    emitSerializedTypeNode(parameterType);
                                }
                                else {
                                    emitSerializedTypeOfNode(parameters[i]);
                                }
                            }
                        }
                    }
                }
            }
            /** Serializes the return type of function. Used by the __metadata decorator for a method. */
            function emitSerializedReturnTypeOfNode(node) {
                if (node && ts.isFunctionLike(node)) {
                    if (node.type) {
                        emitSerializedTypeNode(node.type);
                        return;
                    }
                    else if (ts.isAsyncFunctionLike(node)) {
                        write("Promise");
                        return;
                    }
                }
                write("void 0");
            }
            function emitSerializedTypeMetadata(node, writeComma) {
                // This method emits the serialized type metadata for a decorator target.
                // The caller should have already tested whether the node has decorators.
                var argumentsWritten = 0;
                if (compilerOptions.emitDecoratorMetadata) {
                    if (shouldEmitTypeMetadata(node)) {
                        if (writeComma) {
                            write(", ");
                        }
                        writeLine();
                        write("__metadata('design:type', ");
                        emitSerializedTypeOfNode(node);
                        write(")");
                        argumentsWritten++;
                    }
                    if (shouldEmitParamTypesMetadata(node)) {
                        if (writeComma || argumentsWritten) {
                            write(", ");
                        }
                        writeLine();
                        write("__metadata('design:paramtypes', [");
                        emitSerializedParameterTypesOfNode(node);
                        write("])");
                        argumentsWritten++;
                    }
                    if (shouldEmitReturnTypeMetadata(node)) {
                        if (writeComma || argumentsWritten) {
                            write(", ");
                        }
                        writeLine();
                        write("__metadata('design:returntype', ");
                        emitSerializedReturnTypeOfNode(node);
                        write(")");
                        argumentsWritten++;
                    }
                }
                return argumentsWritten;
            }
            function emitInterfaceDeclaration(node) {
                emitCommentsOnNotEmittedNode(node);
            }
            function shouldEmitEnumDeclaration(node) {
                var isConstEnum = ts.isConst(node);
                return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules;
            }
            function emitEnumDeclaration(node) {
                // const enums are completely erased during compilation.
                if (!shouldEmitEnumDeclaration(node)) {
                    return;
                }
                if (!shouldHoistDeclarationInSystemJsModule(node)) {
                    // do not emit var if variable was already hoisted
                    var isES6ExportedEnum = isES6ExportedDeclaration(node);
                    if (!(node.flags & 1 /* Export */) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, 224 /* EnumDeclaration */))) {
                        emitStart(node);
                        if (isES6ExportedEnum) {
                            write("export ");
                        }
                        write("var ");
                        emit(node.name);
                        emitEnd(node);
                        write(";");
                    }
                }
                writeLine();
                emitStart(node);
                write("(function (");
                emitStart(node.name);
                write(getGeneratedNameForNode(node));
                emitEnd(node.name);
                write(") {");
                increaseIndent();
                emitLines(node.members);
                decreaseIndent();
                writeLine();
                emitToken(16 /* CloseBraceToken */, node.members.end);
                write(")(");
                emitModuleMemberName(node);
                write(" || (");
                emitModuleMemberName(node);
                write(" = {}));");
                emitEnd(node);
                if (!isES6ExportedDeclaration(node) && node.flags & 1 /* Export */ && !shouldHoistDeclarationInSystemJsModule(node)) {
                    // do not emit var if variable was already hoisted
                    writeLine();
                    emitStart(node);
                    write("var ");
                    emit(node.name);
                    write(" = ");
                    emitModuleMemberName(node);
                    emitEnd(node);
                    write(";");
                }
                if (modulekind !== ts.ModuleKind.ES6 && node.parent === currentSourceFile) {
                    if (modulekind === ts.ModuleKind.System && (node.flags & 1 /* Export */)) {
                        // write the call to exporter for enum
                        writeLine();
                        write(exportFunctionForFile + "(\"");
                        emitDeclarationName(node);
                        write("\", ");
                        emitDeclarationName(node);
                        write(");");
                    }
                    emitExportMemberAssignments(node.name);
                }
            }
            function emitEnumMember(node) {
                var enumParent = node.parent;
                emitStart(node);
                write(getGeneratedNameForNode(enumParent));
                write("[");
                write(getGeneratedNameForNode(enumParent));
                write("[");
                emitExpressionForPropertyName(node.name);
                write("] = ");
                writeEnumMemberDeclarationValue(node);
                write("] = ");
                emitExpressionForPropertyName(node.name);
                emitEnd(node);
                write(";");
            }
            function writeEnumMemberDeclarationValue(member) {
                var value = resolver.getConstantValue(member);
                if (value !== undefined) {
                    write(value.toString());
                    return;
                }
                else if (member.initializer) {
                    emit(member.initializer);
                }
                else {
                    write("undefined");
                }
            }
            function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
                if (moduleDeclaration.body && moduleDeclaration.body.kind === 225 /* ModuleDeclaration */) {
                    var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
                    return recursiveInnerModule || moduleDeclaration.body;
                }
            }
            function shouldEmitModuleDeclaration(node) {
                return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules);
            }
            function isModuleMergedWithES6Class(node) {
                return languageVersion === 2 /* ES6 */ && !!(resolver.getNodeCheckFlags(node) & 32768 /* LexicalModuleMergesWithClass */);
            }
            function isFirstDeclarationOfKind(node, declarations, kind) {
                return !ts.forEach(declarations, function (declaration) { return declaration.kind === kind && declaration.pos < node.pos; });
            }
            function emitModuleDeclaration(node) {
                // Emit only if this module is non-ambient.
                var shouldEmit = shouldEmitModuleDeclaration(node);
                if (!shouldEmit) {
                    return emitCommentsOnNotEmittedNode(node);
                }
                var hoistedInDeclarationScope = shouldHoistDeclarationInSystemJsModule(node);
                var emitVarForModule = !hoistedInDeclarationScope && !isModuleMergedWithES6Class(node);
                if (emitVarForModule) {
                    var isES6ExportedNamespace = isES6ExportedDeclaration(node);
                    if (!isES6ExportedNamespace || isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, 225 /* ModuleDeclaration */)) {
                        emitStart(node);
                        if (isES6ExportedNamespace) {
                            write("export ");
                        }
                        write("var ");
                        emit(node.name);
                        write(";");
                        emitEnd(node);
                        writeLine();
                    }
                }
                emitStart(node);
                write("(function (");
                emitStart(node.name);
                write(getGeneratedNameForNode(node));
                emitEnd(node.name);
                write(") ");
                ts.Debug.assert(node.body !== undefined); // node.body must exist, as this is a non-ambient module
                if (node.body.kind === 226 /* ModuleBlock */) {
                    var saveConvertedLoopState = convertedLoopState;
                    var saveTempFlags = tempFlags;
                    var saveTempVariables = tempVariables;
                    convertedLoopState = undefined;
                    tempFlags = 0;
                    tempVariables = undefined;
                    emit(node.body);
                    ts.Debug.assert(convertedLoopState === undefined);
                    convertedLoopState = saveConvertedLoopState;
                    tempFlags = saveTempFlags;
                    tempVariables = saveTempVariables;
                }
                else {
                    write("{");
                    increaseIndent();
                    emitCaptureThisForNodeIfNecessary(node);
                    writeLine();
                    emit(node.body);
                    decreaseIndent();
                    writeLine();
                    var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
                    emitToken(16 /* CloseBraceToken */, moduleBlock.statements.end);
                }
                write(")(");
                // write moduleDecl = containingModule.m only if it is not exported es6 module member
                if ((node.flags & 1 /* Export */) && !isES6ExportedDeclaration(node)) {
                    emit(node.name);
                    write(" = ");
                }
                emitModuleMemberName(node);
                write(" || (");
                emitModuleMemberName(node);
                write(" = {}));");
                emitEnd(node);
                if (!isES6ExportedDeclaration(node) && node.name.kind === 69 /* Identifier */ && node.parent === currentSourceFile) {
                    if (modulekind === ts.ModuleKind.System && (node.flags & 1 /* Export */)) {
                        writeLine();
                        write(exportFunctionForFile + "(\"");
                        emitDeclarationName(node);
                        write("\", ");
                        emitDeclarationName(node);
                        write(");");
                    }
                    emitExportMemberAssignments(node.name);
                }
            }
            /*
             * 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) {
                if (renamedDependencies && ts.hasProperty(renamedDependencies, moduleName.text)) {
                    return "\"" + renamedDependencies[moduleName.text] + "\"";
                }
                return undefined;
            }
            function emitRequire(moduleName) {
                if (moduleName.kind === 9 /* StringLiteral */) {
                    write("require(");
                    var text = tryRenameExternalModule(moduleName);
                    if (text) {
                        write(text);
                    }
                    else {
                        emitStart(moduleName);
                        emitLiteral(moduleName);
                        emitEnd(moduleName);
                    }
                    emitToken(18 /* CloseParenToken */, moduleName.end);
                }
                else {
                    write("require()");
                }
            }
            function getNamespaceDeclarationNode(node) {
                if (node.kind === 229 /* ImportEqualsDeclaration */) {
                    return node;
                }
                var importClause = node.importClause;
                if (importClause && importClause.namedBindings && importClause.namedBindings.kind === 232 /* NamespaceImport */) {
                    return importClause.namedBindings;
                }
            }
            function isDefaultImport(node) {
                return node.kind === 230 /* ImportDeclaration */ && node.importClause && !!node.importClause.name;
            }
            function emitExportImportAssignments(node) {
                if (ts.isAliasSymbolDeclaration(node) && resolver.isValueAliasDeclaration(node)) {
                    emitExportMemberAssignments(node.name);
                }
                ts.forEachChild(node, emitExportImportAssignments);
            }
            function emitImportDeclaration(node) {
                if (modulekind !== ts.ModuleKind.ES6) {
                    return emitExternalImportDeclaration(node);
                }
                // ES6 import
                if (node.importClause) {
                    var shouldEmitDefaultBindings = resolver.isReferencedAliasDeclaration(node.importClause);
                    var shouldEmitNamedBindings = node.importClause.namedBindings && resolver.isReferencedAliasDeclaration(node.importClause.namedBindings, /* checkChildren */ true);
                    if (shouldEmitDefaultBindings || shouldEmitNamedBindings) {
                        write("import ");
                        emitStart(node.importClause);
                        if (shouldEmitDefaultBindings) {
                            emit(node.importClause.name);
                            if (shouldEmitNamedBindings) {
                                write(", ");
                            }
                        }
                        if (shouldEmitNamedBindings) {
                            emitLeadingComments(node.importClause.namedBindings);
                            emitStart(node.importClause.namedBindings);
                            if (node.importClause.namedBindings.kind === 232 /* NamespaceImport */) {
                                write("* as ");
                                emit(node.importClause.namedBindings.name);
                            }
                            else {
                                write("{ ");
                                emitExportOrImportSpecifierList(node.importClause.namedBindings.elements, resolver.isReferencedAliasDeclaration);
                                write(" }");
                            }
                            emitEnd(node.importClause.namedBindings);
                            emitTrailingComments(node.importClause.namedBindings);
                        }
                        emitEnd(node.importClause);
                        write(" from ");
                        emit(node.moduleSpecifier);
                        write(";");
                    }
                }
                else {
                    write("import ");
                    emit(node.moduleSpecifier);
                    write(";");
                }
            }
            function emitExternalImportDeclaration(node) {
                if (ts.contains(externalImports, node)) {
                    var isExportedImport = node.kind === 229 /* ImportEqualsDeclaration */ && (node.flags & 1 /* Export */) !== 0;
                    var namespaceDeclaration = getNamespaceDeclarationNode(node);
                    var varOrConst = (languageVersion <= 1 /* ES5 */) ? "var " : "const ";
                    if (modulekind !== ts.ModuleKind.AMD) {
                        emitLeadingComments(node);
                        emitStart(node);
                        if (namespaceDeclaration && !isDefaultImport(node)) {
                            // import x = require("foo")
                            // import * as x from "foo"
                            if (!isExportedImport) {
                                write(varOrConst);
                            }
                            ;
                            emitModuleMemberName(namespaceDeclaration);
                            write(" = ");
                        }
                        else {
                            // import "foo"
                            // import x from "foo"
                            // import { x, y } from "foo"
                            // import d, * as x from "foo"
                            // import d, { x, y } from "foo"
                            var isNakedImport = 230 /* ImportDeclaration */ && !node.importClause;
                            if (!isNakedImport) {
                                write(varOrConst);
                                write(getGeneratedNameForNode(node));
                                write(" = ");
                            }
                        }
                        emitRequire(ts.getExternalModuleName(node));
                        if (namespaceDeclaration && isDefaultImport(node)) {
                            // import d, * as x from "foo"
                            write(", ");
                            emitModuleMemberName(namespaceDeclaration);
                            write(" = ");
                            write(getGeneratedNameForNode(node));
                        }
                        write(";");
                        emitEnd(node);
                        emitExportImportAssignments(node);
                        emitTrailingComments(node);
                    }
                    else {
                        if (isExportedImport) {
                            emitModuleMemberName(namespaceDeclaration);
                            write(" = ");
                            emit(namespaceDeclaration.name);
                            write(";");
                        }
                        else if (namespaceDeclaration && isDefaultImport(node)) {
                            // import d, * as x from "foo"
                            write(varOrConst);
                            emitModuleMemberName(namespaceDeclaration);
                            write(" = ");
                            write(getGeneratedNameForNode(node));
                            write(";");
                        }
                        emitExportImportAssignments(node);
                    }
                }
            }
            function emitImportEqualsDeclaration(node) {
                if (ts.isExternalModuleImportEqualsDeclaration(node)) {
                    emitExternalImportDeclaration(node);
                    return;
                }
                // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
                // - current file is not external module
                // - import declaration is top level and target is value imported by entity name
                if (resolver.isReferencedAliasDeclaration(node) ||
                    (!isCurrentFileExternalModule && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
                    emitLeadingComments(node);
                    emitStart(node);
                    // variable declaration for import-equals declaration can be hoisted in system modules
                    // in this case 'var' should be omitted and emit should contain only initialization
                    var variableDeclarationIsHoisted = shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ true);
                    // is it top level export import v = a.b.c in system module?
                    // if yes - it needs to be rewritten as exporter('v', v = a.b.c)
                    var isExported = isSourceFileLevelDeclarationInSystemJsModule(node, /*isExported*/ true);
                    if (!variableDeclarationIsHoisted) {
                        ts.Debug.assert(!isExported);
                        if (isES6ExportedDeclaration(node)) {
                            write("export ");
                            write("var ");
                        }
                        else if (!(node.flags & 1 /* Export */)) {
                            write("var ");
                        }
                    }
                    if (isExported) {
                        write(exportFunctionForFile + "(\"");
                        emitNodeWithoutSourceMap(node.name);
                        write("\", ");
                    }
                    emitModuleMemberName(node);
                    write(" = ");
                    emit(node.moduleReference);
                    if (isExported) {
                        write(")");
                    }
                    write(";");
                    emitEnd(node);
                    emitExportImportAssignments(node);
                    emitTrailingComments(node);
                }
            }
            function emitExportDeclaration(node) {
                ts.Debug.assert(modulekind !== ts.ModuleKind.System);
                if (modulekind !== ts.ModuleKind.ES6) {
                    if (node.moduleSpecifier && (!node.exportClause || resolver.isValueAliasDeclaration(node))) {
                        emitStart(node);
                        var generatedName = getGeneratedNameForNode(node);
                        if (node.exportClause) {
                            // export { x, y, ... } from "foo"
                            if (modulekind !== ts.ModuleKind.AMD) {
                                write("var ");
                                write(generatedName);
                                write(" = ");
                                emitRequire(ts.getExternalModuleName(node));
                                write(";");
                            }
                            for (var _a = 0, _b = node.exportClause.elements; _a < _b.length; _a++) {
                                var specifier = _b[_a];
                                if (resolver.isValueAliasDeclaration(specifier)) {
                                    writeLine();
                                    emitStart(specifier);
                                    emitContainingModuleName(specifier);
                                    write(".");
                                    emitNodeWithCommentsAndWithoutSourcemap(specifier.name);
                                    write(" = ");
                                    write(generatedName);
                                    write(".");
                                    emitNodeWithCommentsAndWithoutSourcemap(specifier.propertyName || specifier.name);
                                    write(";");
                                    emitEnd(specifier);
                                }
                            }
                        }
                        else {
                            // export * from "foo"
                            if (hasExportStarsToExportValues && resolver.moduleExportsSomeValue(node.moduleSpecifier)) {
                                writeLine();
                                write("__export(");
                                if (modulekind !== ts.ModuleKind.AMD) {
                                    emitRequire(ts.getExternalModuleName(node));
                                }
                                else {
                                    write(generatedName);
                                }
                                write(");");
                            }
                        }
                        emitEnd(node);
                    }
                }
                else {
                    if (!node.exportClause || resolver.isValueAliasDeclaration(node)) {
                        write("export ");
                        if (node.exportClause) {
                            // export { x, y, ... }
                            write("{ ");
                            emitExportOrImportSpecifierList(node.exportClause.elements, resolver.isValueAliasDeclaration);
                            write(" }");
                        }
                        else {
                            write("*");
                        }
                        if (node.moduleSpecifier) {
                            write(" from ");
                            emit(node.moduleSpecifier);
                        }
                        write(";");
                    }
                }
            }
            function emitExportOrImportSpecifierList(specifiers, shouldEmit) {
                ts.Debug.assert(modulekind === ts.ModuleKind.ES6);
                var needsComma = false;
                for (var _a = 0, specifiers_1 = specifiers; _a < specifiers_1.length; _a++) {
                    var specifier = specifiers_1[_a];
                    if (shouldEmit(specifier)) {
                        if (needsComma) {
                            write(", ");
                        }
                        if (specifier.propertyName) {
                            emit(specifier.propertyName);
                            write(" as ");
                        }
                        emit(specifier.name);
                        needsComma = true;
                    }
                }
            }
            function emitExportAssignment(node) {
                if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
                    if (modulekind === ts.ModuleKind.ES6) {
                        writeLine();
                        emitStart(node);
                        write("export default ");
                        var expression = node.expression;
                        emit(expression);
                        if (expression.kind !== 220 /* FunctionDeclaration */ &&
                            expression.kind !== 221 /* ClassDeclaration */) {
                            write(";");
                        }
                        emitEnd(node);
                    }
                    else {
                        writeLine();
                        emitStart(node);
                        if (modulekind === ts.ModuleKind.System) {
                            write(exportFunctionForFile + "(\"default\",");
                            emit(node.expression);
                            write(")");
                        }
                        else {
                            emitEs6ExportDefaultCompat(node);
                            emitContainingModuleName(node);
                            if (languageVersion === 0 /* ES3 */) {
                                write('["default"] = ');
                            }
                            else {
                                write(".default = ");
                            }
                            emit(node.expression);
                        }
                        write(";");
                        emitEnd(node);
                    }
                }
            }
            function collectExternalModuleInfo(sourceFile) {
                externalImports = [];
                exportSpecifiers = {};
                exportEquals = undefined;
                hasExportStarsToExportValues = false;
                for (var _a = 0, _b = sourceFile.statements; _a < _b.length; _a++) {
                    var node = _b[_a];
                    switch (node.kind) {
                        case 230 /* ImportDeclaration */:
                            if (!node.importClause ||
                                resolver.isReferencedAliasDeclaration(node.importClause, /*checkChildren*/ true)) {
                                // import "mod"
                                // import x from "mod" where x is referenced
                                // import * as x from "mod" where x is referenced
                                // import { x, y } from "mod" where at least one import is referenced
                                externalImports.push(node);
                            }
                            break;
                        case 229 /* ImportEqualsDeclaration */:
                            if (node.moduleReference.kind === 240 /* ExternalModuleReference */ && resolver.isReferencedAliasDeclaration(node)) {
                                // import x = require("mod") where x is referenced
                                externalImports.push(node);
                            }
                            break;
                        case 236 /* ExportDeclaration */:
                            if (node.moduleSpecifier) {
                                if (!node.exportClause) {
                                    // export * from "mod"
                                    if (resolver.moduleExportsSomeValue(node.moduleSpecifier)) {
                                        externalImports.push(node);
                                        hasExportStarsToExportValues = true;
                                    }
                                }
                                else if (resolver.isValueAliasDeclaration(node)) {
                                    // export { x, y } from "mod" where at least one export is a value symbol
                                    externalImports.push(node);
                                }
                            }
                            else {
                                // export { x, y }
                                for (var _c = 0, _d = node.exportClause.elements; _c < _d.length; _c++) {
                                    var specifier = _d[_c];
                                    var name_30 = (specifier.propertyName || specifier.name).text;
                                    (exportSpecifiers[name_30] || (exportSpecifiers[name_30] = [])).push(specifier);
                                }
                            }
                            break;
                        case 235 /* ExportAssignment */:
                            if (node.isExportEquals && !exportEquals) {
                                // export = x
                                exportEquals = node;
                            }
                            break;
                    }
                }
            }
            function emitExportStarHelper() {
                if (hasExportStarsToExportValues) {
                    writeLine();
                    write("function __export(m) {");
                    increaseIndent();
                    writeLine();
                    write("for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];");
                    decreaseIndent();
                    writeLine();
                    write("}");
                }
            }
            function getLocalNameForExternalImport(node) {
                var namespaceDeclaration = getNamespaceDeclarationNode(node);
                if (namespaceDeclaration && !isDefaultImport(node)) {
                    return ts.getTextOfNodeFromSourceText(currentText, namespaceDeclaration.name);
                }
                if (node.kind === 230 /* ImportDeclaration */ && node.importClause) {
                    return getGeneratedNameForNode(node);
                }
                if (node.kind === 236 /* ExportDeclaration */ && node.moduleSpecifier) {
                    return getGeneratedNameForNode(node);
                }
            }
            function getExternalModuleNameText(importNode, emitRelativePathAsModuleName) {
                if (emitRelativePathAsModuleName) {
                    var name_31 = getExternalModuleNameFromDeclaration(host, resolver, importNode);
                    if (name_31) {
                        return "\"" + name_31 + "\"";
                    }
                }
                var moduleName = ts.getExternalModuleName(importNode);
                if (moduleName.kind === 9 /* StringLiteral */) {
                    return tryRenameExternalModule(moduleName) || getLiteralText(moduleName);
                }
                return undefined;
            }
            function emitVariableDeclarationsForImports() {
                if (externalImports.length === 0) {
                    return;
                }
                writeLine();
                var started = false;
                for (var _a = 0, externalImports_1 = externalImports; _a < externalImports_1.length; _a++) {
                    var importNode = externalImports_1[_a];
                    // do not create variable declaration for exports and imports that lack import clause
                    var skipNode = importNode.kind === 236 /* ExportDeclaration */ ||
                        (importNode.kind === 230 /* ImportDeclaration */ && !importNode.importClause);
                    if (skipNode) {
                        continue;
                    }
                    if (!started) {
                        write("var ");
                        started = true;
                    }
                    else {
                        write(", ");
                    }
                    write(getLocalNameForExternalImport(importNode));
                }
                if (started) {
                    write(";");
                }
            }
            function emitLocalStorageForExportedNamesIfNecessary(exportedDeclarations) {
                // 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 exports.
                if (!hasExportStarsToExportValues) {
                    // local names set is needed only in presence of star exports
                    return undefined;
                }
                // local names set should only be added if we have anything exported
                if (!exportedDeclarations && ts.isEmpty(exportSpecifiers)) {
                    // no exported declarations (export var ...) or export specifiers (export {x})
                    // check if we have any non star export declarations.
                    var hasExportDeclarationWithExportClause = false;
                    for (var _a = 0, externalImports_2 = externalImports; _a < externalImports_2.length; _a++) {
                        var externalImport = externalImports_2[_a];
                        if (externalImport.kind === 236 /* ExportDeclaration */ && externalImport.exportClause) {
                            hasExportDeclarationWithExportClause = true;
                            break;
                        }
                    }
                    if (!hasExportDeclarationWithExportClause) {
                        // we still need to emit exportStar helper
                        return emitExportStarFunction(/*localNames*/ undefined);
                    }
                }
                var exportedNamesStorageRef = makeUniqueName("exportedNames");
                writeLine();
                write("var " + exportedNamesStorageRef + " = {");
                increaseIndent();
                var started = false;
                if (exportedDeclarations) {
                    for (var i = 0; i < exportedDeclarations.length; i++) {
                        // write name of exported declaration, i.e 'export var x...'
                        writeExportedName(exportedDeclarations[i]);
                    }
                }
                if (exportSpecifiers) {
                    for (var n in exportSpecifiers) {
                        for (var _b = 0, _c = exportSpecifiers[n]; _b < _c.length; _b++) {
                            var specifier = _c[_b];
                            // write name of export specified, i.e. 'export {x}'
                            writeExportedName(specifier.name);
                        }
                    }
                }
                for (var _d = 0, externalImports_3 = externalImports; _d < externalImports_3.length; _d++) {
                    var externalImport = externalImports_3[_d];
                    if (externalImport.kind !== 236 /* ExportDeclaration */) {
                        continue;
                    }
                    var exportDecl = externalImport;
                    if (!exportDecl.exportClause) {
                        // export * from ...
                        continue;
                    }
                    for (var _e = 0, _f = exportDecl.exportClause.elements; _e < _f.length; _e++) {
                        var element = _f[_e];
                        // write name of indirectly exported entry, i.e. 'export {x} from ...'
                        writeExportedName(element.name || element.propertyName);
                    }
                }
                decreaseIndent();
                writeLine();
                write("};");
                return emitExportStarFunction(exportedNamesStorageRef);
                function emitExportStarFunction(localNames) {
                    var exportStarFunction = makeUniqueName("exportStar");
                    writeLine();
                    // define an export star helper function
                    write("function " + exportStarFunction + "(m) {");
                    increaseIndent();
                    writeLine();
                    write("var exports = {};");
                    writeLine();
                    write("for(var n in m) {");
                    increaseIndent();
                    writeLine();
                    write("if (n !== \"default\"");
                    if (localNames) {
                        write("&& !" + localNames + ".hasOwnProperty(n)");
                    }
                    write(") exports[n] = m[n];");
                    decreaseIndent();
                    writeLine();
                    write("}");
                    writeLine();
                    write(exportFunctionForFile + "(exports);");
                    decreaseIndent();
                    writeLine();
                    write("}");
                    return exportStarFunction;
                }
                function writeExportedName(node) {
                    // do not record default exports
                    // they are local to module and never overwritten (explicitly skipped) by star export
                    if (node.kind !== 69 /* Identifier */ && node.flags & 512 /* Default */) {
                        return;
                    }
                    if (started) {
                        write(",");
                    }
                    else {
                        started = true;
                    }
                    writeLine();
                    write("'");
                    if (node.kind === 69 /* Identifier */) {
                        emitNodeWithCommentsAndWithoutSourcemap(node);
                    }
                    else {
                        emitDeclarationName(node);
                    }
                    write("': true");
                }
            }
            function processTopLevelVariableAndFunctionDeclarations(node) {
                // per ES6 spec:
                // 15.2.1.16.4 ModuleDeclarationInstantiation() Concrete Method
                // - var declarations are initialized to undefined - 14.a.ii
                // - function/generator declarations are instantiated - 16.a.iv
                // this means that after module is instantiated but before its evaluation
                // exported functions are already accessible at import sites
                // in theory we should hoist only exported functions and its dependencies
                // in practice to simplify things we'll hoist all source level functions and variable declaration
                // including variables declarations for module and class declarations
                var hoistedVars;
                var hoistedFunctionDeclarations;
                var exportedDeclarations;
                visit(node);
                if (hoistedVars) {
                    writeLine();
                    write("var ");
                    var seen = {};
                    for (var i = 0; i < hoistedVars.length; i++) {
                        var local = hoistedVars[i];
                        var name_32 = local.kind === 69 /* Identifier */
                            ? local
                            : local.name;
                        if (name_32) {
                            // do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables
                            var text = ts.unescapeIdentifier(name_32.text);
                            if (ts.hasProperty(seen, text)) {
                                continue;
                            }
                            else {
                                seen[text] = text;
                            }
                        }
                        if (i !== 0) {
                            write(", ");
                        }
                        if (local.kind === 221 /* ClassDeclaration */ || local.kind === 225 /* ModuleDeclaration */ || local.kind === 224 /* EnumDeclaration */) {
                            emitDeclarationName(local);
                        }
                        else {
                            emit(local);
                        }
                        var flags = ts.getCombinedNodeFlags(local.kind === 69 /* Identifier */ ? local.parent : local);
                        if (flags & 1 /* Export */) {
                            if (!exportedDeclarations) {
                                exportedDeclarations = [];
                            }
                            exportedDeclarations.push(local);
                        }
                    }
                    write(";");
                }
                if (hoistedFunctionDeclarations) {
                    for (var _a = 0, hoistedFunctionDeclarations_1 = hoistedFunctionDeclarations; _a < hoistedFunctionDeclarations_1.length; _a++) {
                        var f = hoistedFunctionDeclarations_1[_a];
                        writeLine();
                        emit(f);
                        if (f.flags & 1 /* Export */) {
                            if (!exportedDeclarations) {
                                exportedDeclarations = [];
                            }
                            exportedDeclarations.push(f);
                        }
                    }
                }
                return exportedDeclarations;
                function visit(node) {
                    if (node.flags & 2 /* Ambient */) {
                        return;
                    }
                    if (node.kind === 220 /* FunctionDeclaration */) {
                        if (!hoistedFunctionDeclarations) {
                            hoistedFunctionDeclarations = [];
                        }
                        hoistedFunctionDeclarations.push(node);
                        return;
                    }
                    if (node.kind === 221 /* ClassDeclaration */) {
                        if (!hoistedVars) {
                            hoistedVars = [];
                        }
                        hoistedVars.push(node);
                        return;
                    }
                    if (node.kind === 224 /* EnumDeclaration */) {
                        if (shouldEmitEnumDeclaration(node)) {
                            if (!hoistedVars) {
                                hoistedVars = [];
                            }
                            hoistedVars.push(node);
                        }
                        return;
                    }
                    if (node.kind === 225 /* ModuleDeclaration */) {
                        if (shouldEmitModuleDeclaration(node)) {
                            if (!hoistedVars) {
                                hoistedVars = [];
                            }
                            hoistedVars.push(node);
                        }
                        return;
                    }
                    if (node.kind === 218 /* VariableDeclaration */ || node.kind === 169 /* BindingElement */) {
                        if (shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ false)) {
                            var name_33 = node.name;
                            if (name_33.kind === 69 /* Identifier */) {
                                if (!hoistedVars) {
                                    hoistedVars = [];
                                }
                                hoistedVars.push(name_33);
                            }
                            else {
                                ts.forEachChild(name_33, visit);
                            }
                        }
                        return;
                    }
                    if (ts.isInternalModuleImportEqualsDeclaration(node) && resolver.isValueAliasDeclaration(node)) {
                        if (!hoistedVars) {
                            hoistedVars = [];
                        }
                        hoistedVars.push(node.name);
                        return;
                    }
                    if (ts.isBindingPattern(node)) {
                        ts.forEach(node.elements, visit);
                        return;
                    }
                    if (!ts.isDeclaration(node)) {
                        ts.forEachChild(node, visit);
                    }
                }
            }
            function shouldHoistVariable(node, checkIfSourceFileLevelDecl) {
                if (checkIfSourceFileLevelDecl && !shouldHoistDeclarationInSystemJsModule(node)) {
                    return false;
                }
                // hoist variable if
                // - it is not block scoped
                // - it is top level block scoped
                // if block scoped variables are nested in some another block then
                // no other functions can use them except ones that are defined at least in the same block
                return (ts.getCombinedNodeFlags(node) & 3072 /* BlockScoped */) === 0 ||
                    ts.getEnclosingBlockScopeContainer(node).kind === 256 /* SourceFile */;
            }
            function isCurrentFileSystemExternalModule() {
                return modulekind === ts.ModuleKind.System && isCurrentFileExternalModule;
            }
            function emitSystemModuleBody(node, dependencyGroups, startIndex) {
                // shape of the body in system modules:
                // function (exports) {
                //     <list of local aliases for imports>
                //     <hoisted function declarations>
                //     <hoisted variable 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) {
                //     var file1; // local alias
                //     var y;
                //     function foo() { return y + file1.x(); }
                //     exports("foo", foo);
                //     return {
                //         setters: [
                //             function(v) { file1 = v }
                //         ],
                //         execute(): function() {
                //             y = 1;
                //             console.log(y);
                //         }
                //     };
                // }
                emitVariableDeclarationsForImports();
                writeLine();
                var exportedDeclarations = processTopLevelVariableAndFunctionDeclarations(node);
                var exportStarFunction = emitLocalStorageForExportedNamesIfNecessary(exportedDeclarations);
                writeLine();
                write("return {");
                increaseIndent();
                writeLine();
                emitSetters(exportStarFunction, dependencyGroups);
                writeLine();
                emitExecute(node, startIndex);
                decreaseIndent();
                writeLine();
                write("}"); // return
                emitTempDeclarations(/*newLine*/ true);
            }
            function emitSetters(exportStarFunction, dependencyGroups) {
                write("setters:[");
                for (var i = 0; i < dependencyGroups.length; i++) {
                    if (i !== 0) {
                        write(",");
                    }
                    writeLine();
                    increaseIndent();
                    var group = dependencyGroups[i];
                    // derive a unique name for parameter from the first named entry in the group
                    var parameterName = makeUniqueName(ts.forEach(group, getLocalNameForExternalImport) || "");
                    write("function (" + parameterName + ") {");
                    increaseIndent();
                    for (var _a = 0, group_1 = group; _a < group_1.length; _a++) {
                        var entry = group_1[_a];
                        var importVariableName = getLocalNameForExternalImport(entry) || "";
                        switch (entry.kind) {
                            case 230 /* ImportDeclaration */:
                                if (!entry.importClause) {
                                    // 'import "..."' case
                                    // module is imported only for side-effects, no emit required
                                    break;
                                }
                            // fall-through
                            case 229 /* ImportEqualsDeclaration */:
                                ts.Debug.assert(importVariableName !== "");
                                writeLine();
                                // save import into the local
                                write(importVariableName + " = " + parameterName + ";");
                                writeLine();
                                break;
                            case 236 /* ExportDeclaration */:
                                ts.Debug.assert(importVariableName !== "");
                                if (entry.exportClause) {
                                    // export {a, b as c} from 'foo'
                                    // emit as:
                                    // exports_({
                                    //    "a": _["a"],
                                    //    "c": _["b"]
                                    // });
                                    writeLine();
                                    write(exportFunctionForFile + "({");
                                    writeLine();
                                    increaseIndent();
                                    for (var i_1 = 0, len = entry.exportClause.elements.length; i_1 < len; i_1++) {
                                        if (i_1 !== 0) {
                                            write(",");
                                            writeLine();
                                        }
                                        var e = entry.exportClause.elements[i_1];
                                        write("\"");
                                        emitNodeWithCommentsAndWithoutSourcemap(e.name);
                                        write("\": " + parameterName + "[\"");
                                        emitNodeWithCommentsAndWithoutSourcemap(e.propertyName || e.name);
                                        write("\"]");
                                    }
                                    decreaseIndent();
                                    writeLine();
                                    write("});");
                                }
                                else {
                                    // collectExternalModuleInfo prefilters star exports to keep only ones that export values
                                    // this means that check 'resolver.moduleExportsSomeValue' is redundant and can be omitted here
                                    writeLine();
                                    // export * from 'foo'
                                    // emit as:
                                    // exportStar(_foo);
                                    write(exportStarFunction + "(" + parameterName + ");");
                                }
                                writeLine();
                                break;
                        }
                    }
                    decreaseIndent();
                    write("}");
                    decreaseIndent();
                }
                write("],");
            }
            function emitExecute(node, startIndex) {
                write("execute: function() {");
                increaseIndent();
                writeLine();
                for (var i = startIndex; i < node.statements.length; i++) {
                    var statement = node.statements[i];
                    switch (statement.kind) {
                        // - function declarations are not emitted because they were already hoisted
                        // - import declarations are not emitted since they are already handled in setters
                        // - export declarations with module specifiers are not emitted since they were already written in setters
                        // - export declarations without module specifiers are emitted preserving the order
                        case 220 /* FunctionDeclaration */:
                        case 230 /* ImportDeclaration */:
                            continue;
                        case 236 /* ExportDeclaration */:
                            if (!statement.moduleSpecifier) {
                                for (var _a = 0, _b = statement.exportClause.elements; _a < _b.length; _a++) {
                                    var element = _b[_a];
                                    // write call to exporter function for every export specifier in exports list
                                    emitExportSpecifierInSystemModule(element);
                                }
                            }
                            continue;
                        case 229 /* ImportEqualsDeclaration */:
                            if (!ts.isInternalModuleImportEqualsDeclaration(statement)) {
                                // - import equals declarations that import external modules are not emitted
                                continue;
                            }
                        // fall-though for import declarations that import internal modules
                        default:
                            writeLine();
                            emit(statement);
                    }
                }
                decreaseIndent();
                writeLine();
                write("}"); // execute
            }
            function writeModuleName(node, emitRelativePathAsModuleName) {
                var moduleName = node.moduleName;
                if (moduleName || (emitRelativePathAsModuleName && (moduleName = getResolvedExternalModuleName(host, node)))) {
                    write("\"" + moduleName + "\", ");
                }
            }
            function emitSystemModule(node, emitRelativePathAsModuleName) {
                collectExternalModuleInfo(node);
                // System modules has the following shape
                // System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
                // 'exports' here is a function 'exports<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 'emitPostfixUnaryExpression' for more details
                ts.Debug.assert(!exportFunctionForFile);
                // make sure that  name of 'exports' function does not conflict with existing identifiers
                exportFunctionForFile = makeUniqueName("exports");
                contextObjectForFile = makeUniqueName("context");
                writeLine();
                write("System.register(");
                writeModuleName(node, emitRelativePathAsModuleName);
                write("[");
                var groupIndices = {};
                var dependencyGroups = [];
                for (var i = 0; i < externalImports.length; i++) {
                    var text = getExternalModuleNameText(externalImports[i], emitRelativePathAsModuleName);
                    if (text === undefined) {
                        continue;
                    }
                    // text should be quoted string
                    // for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
                    var key = text.substr(1, text.length - 2);
                    if (ts.hasProperty(groupIndices, key)) {
                        // deduplicate/group entries in dependency list by the dependency name
                        var groupIndex = groupIndices[key];
                        dependencyGroups[groupIndex].push(externalImports[i]);
                        continue;
                    }
                    else {
                        groupIndices[key] = dependencyGroups.length;
                        dependencyGroups.push([externalImports[i]]);
                    }
                    if (i !== 0) {
                        write(", ");
                    }
                    write(text);
                }
                write("], function(" + exportFunctionForFile + ", " + contextObjectForFile + ") {");
                writeLine();
                increaseIndent();
                var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
                writeLine();
                write("var __moduleName = " + contextObjectForFile + " && " + contextObjectForFile + ".id;");
                writeLine();
                emitEmitHelpers(node);
                emitCaptureThisForNodeIfNecessary(node);
                emitSystemModuleBody(node, dependencyGroups, startIndex);
                decreaseIndent();
                writeLine();
                write("});");
            }
            function getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
                // names of modules with corresponding parameter in the factory function
                var aliasedModuleNames = [];
                // names of modules with no corresponding parameters in factory function
                var unaliasedModuleNames = [];
                var importAliasNames = []; // names of the parameters in the factory function; these
                // parameters need to match the indexes of the corresponding
                // module names in aliasedModuleNames.
                // Fill in amd-dependency tags
                for (var _a = 0, _b = node.amdDependencies; _a < _b.length; _a++) {
                    var amdDependency = _b[_a];
                    if (amdDependency.name) {
                        aliasedModuleNames.push('"' + amdDependency.path + '"');
                        importAliasNames.push(amdDependency.name);
                    }
                    else {
                        unaliasedModuleNames.push('"' + amdDependency.path + '"');
                    }
                }
                for (var _c = 0, externalImports_4 = externalImports; _c < externalImports_4.length; _c++) {
                    var importNode = externalImports_4[_c];
                    // Find the name of the external module
                    var externalModuleName = getExternalModuleNameText(importNode, emitRelativePathAsModuleName);
                    // Find the name of the module alias, if there is one
                    var importAliasName = getLocalNameForExternalImport(importNode);
                    if (includeNonAmdDependencies && importAliasName) {
                        aliasedModuleNames.push(externalModuleName);
                        importAliasNames.push(importAliasName);
                    }
                    else {
                        unaliasedModuleNames.push(externalModuleName);
                    }
                }
                return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
            }
            function emitAMDDependencies(node, includeNonAmdDependencies, emitRelativePathAsModuleName) {
                // An AMD define function has the following shape:
                //     define(id?, dependencies?, factory);
                //
                // This has the shape of
                //     define(name, ["module1", "module2"], function (module1Alias) {
                // The location of the alias in the parameter list in the factory function needs to
                // match the position of the module name in the dependency list.
                //
                // To ensure this is true in cases of modules with no aliases, e.g.:
                // `import "module"` or `<amd-dependency path= "a.css" />`
                // we need to add modules without alias names to the end of the dependencies list
                var dependencyNames = getAMDDependencyNames(node, includeNonAmdDependencies, emitRelativePathAsModuleName);
                emitAMDDependencyList(dependencyNames);
                write(", ");
                emitAMDFactoryHeader(dependencyNames);
            }
            function emitAMDDependencyList(_a) {
                var aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames;
                write('["require", "exports"');
                if (aliasedModuleNames.length) {
                    write(", ");
                    write(aliasedModuleNames.join(", "));
                }
                if (unaliasedModuleNames.length) {
                    write(", ");
                    write(unaliasedModuleNames.join(", "));
                }
                write("]");
            }
            function emitAMDFactoryHeader(_a) {
                var importAliasNames = _a.importAliasNames;
                write("function (require, exports");
                if (importAliasNames.length) {
                    write(", ");
                    write(importAliasNames.join(", "));
                }
                write(") {");
            }
            function emitAMDModule(node, emitRelativePathAsModuleName) {
                emitEmitHelpers(node);
                collectExternalModuleInfo(node);
                writeLine();
                write("define(");
                writeModuleName(node, emitRelativePathAsModuleName);
                emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName);
                increaseIndent();
                var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
                emitExportStarHelper();
                emitCaptureThisForNodeIfNecessary(node);
                emitLinesStartingAt(node.statements, startIndex);
                emitExportEquals(/*emitAsReturn*/ true);
                emitTempDeclarations(/*newLine*/ true);
                decreaseIndent();
                writeLine();
                write("});");
            }
            function emitCommonJSModule(node) {
                var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
                emitEmitHelpers(node);
                collectExternalModuleInfo(node);
                emitExportStarHelper();
                emitCaptureThisForNodeIfNecessary(node);
                emitLinesStartingAt(node.statements, startIndex);
                emitExportEquals(/*emitAsReturn*/ false);
                emitTempDeclarations(/*newLine*/ true);
            }
            function emitUMDModule(node) {
                emitEmitHelpers(node);
                collectExternalModuleInfo(node);
                var dependencyNames = getAMDDependencyNames(node, /*includeNonAmdDependencies*/ false);
                // Module is detected first to support Browserify users that load into a browser with an AMD loader
                writeLines("(function (factory) {\n    if (typeof module === 'object' && typeof module.exports === 'object') {\n        var v = factory(require, exports); if (v !== undefined) module.exports = v;\n    }\n    else if (typeof define === 'function' && define.amd) {\n        define(");
                emitAMDDependencyList(dependencyNames);
                write(", factory);");
                writeLines("    }\n})(");
                emitAMDFactoryHeader(dependencyNames);
                increaseIndent();
                var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict);
                emitExportStarHelper();
                emitCaptureThisForNodeIfNecessary(node);
                emitLinesStartingAt(node.statements, startIndex);
                emitExportEquals(/*emitAsReturn*/ true);
                emitTempDeclarations(/*newLine*/ true);
                decreaseIndent();
                writeLine();
                write("});");
            }
            function emitES6Module(node) {
                externalImports = undefined;
                exportSpecifiers = undefined;
                exportEquals = undefined;
                hasExportStarsToExportValues = false;
                var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
                emitEmitHelpers(node);
                emitCaptureThisForNodeIfNecessary(node);
                emitLinesStartingAt(node.statements, startIndex);
                emitTempDeclarations(/*newLine*/ true);
                // Emit exportDefault if it exists will happen as part
                // or normal statement emit.
            }
            function emitExportEquals(emitAsReturn) {
                if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) {
                    writeLine();
                    emitStart(exportEquals);
                    write(emitAsReturn ? "return " : "module.exports = ");
                    emit(exportEquals.expression);
                    write(";");
                    emitEnd(exportEquals);
                }
            }
            function emitJsxElement(node) {
                switch (compilerOptions.jsx) {
                    case 2 /* React */:
                        jsxEmitReact(node);
                        break;
                    case 1 /* Preserve */:
                    // Fall back to preserve if None was specified (we'll error earlier)
                    default:
                        jsxEmitPreserve(node);
                        break;
                }
            }
            function trimReactWhitespaceAndApplyEntities(node) {
                var result = undefined;
                var text = ts.getTextOfNode(node, /*includeTrivia*/ true);
                var firstNonWhitespace = 0;
                var lastNonWhitespace = -1;
                // 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
                for (var i = 0; i < text.length; i++) {
                    var c = text.charCodeAt(i);
                    if (ts.isLineBreak(c)) {
                        if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
                            var part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1);
                            result = (result ? result + "\" + ' ' + \"" : "") + ts.escapeString(part);
                        }
                        firstNonWhitespace = -1;
                    }
                    else if (!ts.isWhiteSpaceSingleLine(c)) {
                        lastNonWhitespace = i;
                        if (firstNonWhitespace === -1) {
                            firstNonWhitespace = i;
                        }
                    }
                }
                if (firstNonWhitespace !== -1) {
                    var part = text.substr(firstNonWhitespace);
                    result = (result ? result + "\" + ' ' + \"" : "") + ts.escapeString(part);
                }
                if (result) {
                    // Replace entities like &nbsp;
                    result = result.replace(/&(\w+);/g, function (s, m) {
                        if (entities[m] !== undefined) {
                            var ch = String.fromCharCode(entities[m]);
                            // &quot; needs to be escaped
                            return ch === '"' ? "\\\"" : ch;
                        }
                        else {
                            return s;
                        }
                    });
                }
                return result;
            }
            function isJsxChildEmittable(child) {
                if (child.kind === 248 /* JsxExpression */) {
                    // Don't emit empty expressions
                    return !!child.expression;
                }
                else if (child.kind === 244 /* JsxText */) {
                    // Don't emit empty strings
                    return !!getTextToEmit(child);
                }
                return true;
            }
            ;
            function getTextToEmit(node) {
                switch (compilerOptions.jsx) {
                    case 2 /* React */:
                        var text = trimReactWhitespaceAndApplyEntities(node);
                        if (text === undefined || text.length === 0) {
                            return undefined;
                        }
                        else {
                            return text;
                        }
                    case 1 /* Preserve */:
                    default:
                        return ts.getTextOfNode(node, /*includeTrivia*/ true);
                }
            }
            function emitJsxText(node) {
                switch (compilerOptions.jsx) {
                    case 2 /* React */:
                        write('"');
                        write(trimReactWhitespaceAndApplyEntities(node));
                        write('"');
                        break;
                    case 1 /* Preserve */:
                    default:
                        writer.writeLiteral(ts.getTextOfNode(node, /*includeTrivia*/ true));
                        break;
                }
            }
            function emitJsxExpression(node) {
                if (node.expression) {
                    switch (compilerOptions.jsx) {
                        case 1 /* Preserve */:
                        default:
                            write("{");
                            emit(node.expression);
                            write("}");
                            break;
                        case 2 /* React */:
                            emit(node.expression);
                            break;
                    }
                }
            }
            function isUseStrictPrologue(node) {
                return node.expression.text === "use strict";
            }
            function ensureUseStrictPrologue(startWithNewLine, writeUseStrict) {
                if (writeUseStrict) {
                    if (startWithNewLine) {
                        writeLine();
                    }
                    write("\"use strict\";");
                }
            }
            function emitDirectivePrologues(statements, startWithNewLine, ensureUseStrict) {
                var foundUseStrict = false;
                for (var i = 0; i < statements.length; i++) {
                    if (ts.isPrologueDirective(statements[i])) {
                        if (isUseStrictPrologue(statements[i])) {
                            foundUseStrict = true;
                        }
                        if (startWithNewLine || i > 0) {
                            writeLine();
                        }
                        emit(statements[i]);
                    }
                    else {
                        ensureUseStrictPrologue(startWithNewLine || i > 0, !foundUseStrict && ensureUseStrict);
                        // return index of the first non prologue directive
                        return i;
                    }
                }
                ensureUseStrictPrologue(startWithNewLine, !foundUseStrict && ensureUseStrict);
                return statements.length;
            }
            function writeLines(text) {
                var lines = text.split(/\r\n|\r|\n/g);
                for (var i = 0; i < lines.length; i++) {
                    var line = lines[i];
                    if (line.length) {
                        writeLine();
                        write(line);
                    }
                }
            }
            function emitEmitHelpers(node) {
                // Only emit helpers if the user did not say otherwise.
                if (!compilerOptions.noEmitHelpers) {
                    // Only Emit __extends function when target ES5.
                    // For target ES6 and above, we can emit classDeclaration as is.
                    if (languageVersion < 2 /* ES6 */ && !extendsEmitted && node.flags & 262144 /* HasClassExtends */) {
                        writeLines(extendsHelper);
                        extendsEmitted = true;
                    }
                    if (compilerOptions.jsx !== 1 /* Preserve */ && !assignEmitted && (node.flags & 1073741824 /* HasJsxSpreadAttribute */)) {
                        writeLines(assignHelper);
                        assignEmitted = true;
                    }
                    if (!decorateEmitted && node.flags & 524288 /* HasDecorators */) {
                        writeLines(decorateHelper);
                        if (compilerOptions.emitDecoratorMetadata) {
                            writeLines(metadataHelper);
                        }
                        decorateEmitted = true;
                    }
                    if (!paramEmitted && node.flags & 1048576 /* HasParamDecorators */) {
                        writeLines(paramHelper);
                        paramEmitted = true;
                    }
                    if (!awaiterEmitted && node.flags & 2097152 /* HasAsyncFunctions */) {
                        writeLines(awaiterHelper);
                        awaiterEmitted = true;
                    }
                }
            }
            function emitSourceFileNode(node) {
                // Start new file on new line
                writeLine();
                emitShebang();
                emitDetachedCommentsAndUpdateCommentsInfo(node);
                if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
                    if (isOwnFileEmit || (!ts.isExternalModule(node) && compilerOptions.isolatedModules)) {
                        var emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[ts.ModuleKind.CommonJS];
                        emitModule(node);
                    }
                    else {
                        bundleEmitDelegates[modulekind](node, /*emitRelativePathAsModuleName*/ true);
                    }
                }
                else {
                    // emit prologue directives prior to __extends
                    var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
                    externalImports = undefined;
                    exportSpecifiers = undefined;
                    exportEquals = undefined;
                    hasExportStarsToExportValues = false;
                    emitEmitHelpers(node);
                    emitCaptureThisForNodeIfNecessary(node);
                    emitLinesStartingAt(node.statements, startIndex);
                    emitTempDeclarations(/*newLine*/ true);
                }
                emitLeadingComments(node.endOfFileToken);
            }
            function emit(node) {
                emitNodeConsideringCommentsOption(node, emitNodeWithSourceMap);
            }
            function emitNodeWithCommentsAndWithoutSourcemap(node) {
                emitNodeConsideringCommentsOption(node, emitNodeWithoutSourceMap);
            }
            function emitNodeConsideringCommentsOption(node, emitNodeConsideringSourcemap) {
                if (node) {
                    if (node.flags & 2 /* Ambient */) {
                        return emitCommentsOnNotEmittedNode(node);
                    }
                    if (isSpecializedCommentHandling(node)) {
                        // This is the node that will handle its own comments and sourcemap
                        return emitNodeWithoutSourceMap(node);
                    }
                    var emitComments_1 = shouldEmitLeadingAndTrailingComments(node);
                    if (emitComments_1) {
                        emitLeadingComments(node);
                    }
                    emitNodeConsideringSourcemap(node);
                    if (emitComments_1) {
                        emitTrailingComments(node);
                    }
                }
            }
            function emitNodeWithSourceMap(node) {
                if (node) {
                    emitStart(node);
                    emitNodeWithoutSourceMap(node);
                    emitEnd(node);
                }
            }
            function emitNodeWithoutSourceMap(node) {
                if (node) {
                    emitJavaScriptWorker(node);
                }
            }
            function changeSourceMapEmit(writer) {
                sourceMap = writer;
                emitStart = writer.emitStart;
                emitEnd = writer.emitEnd;
                emitPos = writer.emitPos;
                setSourceFile = writer.setSourceFile;
            }
            function withTemporaryNoSourceMap(callback) {
                var prevSourceMap = sourceMap;
                setSourceMapWriterEmit(ts.getNullSourceMapWriter());
                callback();
                setSourceMapWriterEmit(prevSourceMap);
            }
            function isSpecializedCommentHandling(node) {
                switch (node.kind) {
                    // All of these entities are emitted in a specialized fashion.  As such, we allow
                    // the specialized methods for each to handle the comments on the nodes.
                    case 222 /* InterfaceDeclaration */:
                    case 220 /* FunctionDeclaration */:
                    case 230 /* ImportDeclaration */:
                    case 229 /* ImportEqualsDeclaration */:
                    case 223 /* TypeAliasDeclaration */:
                    case 235 /* ExportAssignment */:
                        return true;
                }
            }
            function shouldEmitLeadingAndTrailingComments(node) {
                switch (node.kind) {
                    case 200 /* VariableStatement */:
                        return shouldEmitLeadingAndTrailingCommentsForVariableStatement(node);
                    case 225 /* ModuleDeclaration */:
                        // Only emit the leading/trailing comments for a module if we're actually
                        // emitting the module as well.
                        return shouldEmitModuleDeclaration(node);
                    case 224 /* EnumDeclaration */:
                        // Only emit the leading/trailing comments for an enum if we're actually
                        // emitting the module as well.
                        return shouldEmitEnumDeclaration(node);
                }
                // If the node is emitted in specialized fashion, dont emit comments as this node will handle
                // emitting comments when emitting itself
                ts.Debug.assert(!isSpecializedCommentHandling(node));
                // If this is the expression body of an arrow function that we're down-leveling,
                // then we don't want to emit comments when we emit the body.  It will have already
                // been taken care of when we emitted the 'return' statement for the function
                // expression body.
                if (node.kind !== 199 /* Block */ &&
                    node.parent &&
                    node.parent.kind === 180 /* ArrowFunction */ &&
                    node.parent.body === node &&
                    languageVersion <= 1 /* ES5 */) {
                    return false;
                }
                // Emit comments for everything else.
                return true;
            }
            function emitJavaScriptWorker(node) {
                // Check if the node can be emitted regardless of the ScriptTarget
                switch (node.kind) {
                    case 69 /* Identifier */:
                        return emitIdentifier(node);
                    case 142 /* Parameter */:
                        return emitParameter(node);
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                        return emitMethod(node);
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        return emitAccessor(node);
                    case 97 /* ThisKeyword */:
                        return emitThis(node);
                    case 95 /* SuperKeyword */:
                        return emitSuper(node);
                    case 93 /* NullKeyword */:
                        return write("null");
                    case 99 /* TrueKeyword */:
                        return write("true");
                    case 84 /* FalseKeyword */:
                        return write("false");
                    case 8 /* NumericLiteral */:
                    case 9 /* StringLiteral */:
                    case 10 /* RegularExpressionLiteral */:
                    case 11 /* NoSubstitutionTemplateLiteral */:
                    case 12 /* TemplateHead */:
                    case 13 /* TemplateMiddle */:
                    case 14 /* TemplateTail */:
                        return emitLiteral(node);
                    case 189 /* TemplateExpression */:
                        return emitTemplateExpression(node);
                    case 197 /* TemplateSpan */:
                        return emitTemplateSpan(node);
                    case 241 /* JsxElement */:
                    case 242 /* JsxSelfClosingElement */:
                        return emitJsxElement(node);
                    case 244 /* JsxText */:
                        return emitJsxText(node);
                    case 248 /* JsxExpression */:
                        return emitJsxExpression(node);
                    case 139 /* QualifiedName */:
                        return emitQualifiedName(node);
                    case 167 /* ObjectBindingPattern */:
                        return emitObjectBindingPattern(node);
                    case 168 /* ArrayBindingPattern */:
                        return emitArrayBindingPattern(node);
                    case 169 /* BindingElement */:
                        return emitBindingElement(node);
                    case 170 /* ArrayLiteralExpression */:
                        return emitArrayLiteral(node);
                    case 171 /* ObjectLiteralExpression */:
                        return emitObjectLiteral(node);
                    case 253 /* PropertyAssignment */:
                        return emitPropertyAssignment(node);
                    case 254 /* ShorthandPropertyAssignment */:
                        return emitShorthandPropertyAssignment(node);
                    case 140 /* ComputedPropertyName */:
                        return emitComputedPropertyName(node);
                    case 172 /* PropertyAccessExpression */:
                        return emitPropertyAccess(node);
                    case 173 /* ElementAccessExpression */:
                        return emitIndexedAccess(node);
                    case 174 /* CallExpression */:
                        return emitCallExpression(node);
                    case 175 /* NewExpression */:
                        return emitNewExpression(node);
                    case 176 /* TaggedTemplateExpression */:
                        return emitTaggedTemplateExpression(node);
                    case 177 /* TypeAssertionExpression */:
                    case 195 /* AsExpression */:
                    case 196 /* NonNullExpression */:
                        return emit(node.expression);
                    case 178 /* ParenthesizedExpression */:
                        return emitParenExpression(node);
                    case 220 /* FunctionDeclaration */:
                    case 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                        return emitFunctionDeclaration(node);
                    case 181 /* DeleteExpression */:
                        return emitDeleteExpression(node);
                    case 182 /* TypeOfExpression */:
                        return emitTypeOfExpression(node);
                    case 183 /* VoidExpression */:
                        return emitVoidExpression(node);
                    case 184 /* AwaitExpression */:
                        return emitAwaitExpression(node);
                    case 185 /* PrefixUnaryExpression */:
                        return emitPrefixUnaryExpression(node);
                    case 186 /* PostfixUnaryExpression */:
                        return emitPostfixUnaryExpression(node);
                    case 187 /* BinaryExpression */:
                        return emitBinaryExpression(node);
                    case 188 /* ConditionalExpression */:
                        return emitConditionalExpression(node);
                    case 191 /* SpreadElementExpression */:
                        return emitSpreadElementExpression(node);
                    case 190 /* YieldExpression */:
                        return emitYieldExpression(node);
                    case 193 /* OmittedExpression */:
                        return;
                    case 199 /* Block */:
                    case 226 /* ModuleBlock */:
                        return emitBlock(node);
                    case 200 /* VariableStatement */:
                        return emitVariableStatement(node);
                    case 201 /* EmptyStatement */:
                        return write(";");
                    case 202 /* ExpressionStatement */:
                        return emitExpressionStatement(node);
                    case 203 /* IfStatement */:
                        return emitIfStatement(node);
                    case 204 /* DoStatement */:
                        return emitDoStatement(node);
                    case 205 /* WhileStatement */:
                        return emitWhileStatement(node);
                    case 206 /* ForStatement */:
                        return emitForStatement(node);
                    case 208 /* ForOfStatement */:
                    case 207 /* ForInStatement */:
                        return emitForInOrForOfStatement(node);
                    case 209 /* ContinueStatement */:
                    case 210 /* BreakStatement */:
                        return emitBreakOrContinueStatement(node);
                    case 211 /* ReturnStatement */:
                        return emitReturnStatement(node);
                    case 212 /* WithStatement */:
                        return emitWithStatement(node);
                    case 213 /* SwitchStatement */:
                        return emitSwitchStatement(node);
                    case 249 /* CaseClause */:
                    case 250 /* DefaultClause */:
                        return emitCaseOrDefaultClause(node);
                    case 214 /* LabeledStatement */:
                        return emitLabeledStatement(node);
                    case 215 /* ThrowStatement */:
                        return emitThrowStatement(node);
                    case 216 /* TryStatement */:
                        return emitTryStatement(node);
                    case 252 /* CatchClause */:
                        return emitCatchClause(node);
                    case 217 /* DebuggerStatement */:
                        return emitDebuggerStatement(node);
                    case 218 /* VariableDeclaration */:
                        return emitVariableDeclaration(node);
                    case 192 /* ClassExpression */:
                        return emitClassExpression(node);
                    case 221 /* ClassDeclaration */:
                        return emitClassDeclaration(node);
                    case 222 /* InterfaceDeclaration */:
                        return emitInterfaceDeclaration(node);
                    case 224 /* EnumDeclaration */:
                        return emitEnumDeclaration(node);
                    case 255 /* EnumMember */:
                        return emitEnumMember(node);
                    case 225 /* ModuleDeclaration */:
                        return emitModuleDeclaration(node);
                    case 230 /* ImportDeclaration */:
                        return emitImportDeclaration(node);
                    case 229 /* ImportEqualsDeclaration */:
                        return emitImportEqualsDeclaration(node);
                    case 236 /* ExportDeclaration */:
                        return emitExportDeclaration(node);
                    case 235 /* ExportAssignment */:
                        return emitExportAssignment(node);
                    case 256 /* SourceFile */:
                        return emitSourceFileNode(node);
                }
            }
            function hasDetachedComments(pos) {
                return detachedCommentsInfo !== undefined && ts.lastOrUndefined(detachedCommentsInfo).nodePos === pos;
            }
            function getLeadingCommentsWithoutDetachedComments() {
                // get the leading comments from detachedPos
                var leadingComments = ts.getLeadingCommentRanges(currentText, ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
                if (detachedCommentsInfo.length - 1) {
                    detachedCommentsInfo.pop();
                }
                else {
                    detachedCommentsInfo = undefined;
                }
                return leadingComments;
            }
            /**
             * Determine if the given comment is a triple-slash
             *
             * @return true if the comment is a triple-slash comment else false
             **/
            function isTripleSlashComment(comment) {
                // 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 (currentText.charCodeAt(comment.pos + 1) === 47 /* slash */ &&
                    comment.pos + 2 < comment.end &&
                    currentText.charCodeAt(comment.pos + 2) === 47 /* slash */) {
                    var textSubStr = currentText.substring(comment.pos, comment.end);
                    return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
                        textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ?
                        true : false;
                }
                return false;
            }
            function getLeadingCommentsToEmit(node) {
                // Emit the leading comments only if the parent's pos doesn't match because parent should take care of emitting these comments
                if (node.parent) {
                    if (node.parent.kind === 256 /* SourceFile */ || node.pos !== node.parent.pos) {
                        if (hasDetachedComments(node.pos)) {
                            // get comments without detached comments
                            return getLeadingCommentsWithoutDetachedComments();
                        }
                        else {
                            // get the leading comments from the node
                            return ts.getLeadingCommentRangesOfNodeFromText(node, currentText);
                        }
                    }
                }
            }
            function getTrailingCommentsToEmit(node) {
                // Emit the trailing comments only if the parent's pos doesn't match because parent should take care of emitting these comments
                if (node.parent) {
                    if (node.parent.kind === 256 /* SourceFile */ || node.end !== node.parent.end) {
                        return ts.getTrailingCommentRanges(currentText, node.end);
                    }
                }
            }
            /**
             * Emit comments associated with node that will not be emitted into JS file
             */
            function emitCommentsOnNotEmittedNode(node) {
                emitLeadingCommentsWorker(node, /*isEmittedNode*/ false);
            }
            function emitLeadingComments(node) {
                return emitLeadingCommentsWorker(node, /*isEmittedNode*/ true);
            }
            function emitLeadingCommentsWorker(node, isEmittedNode) {
                if (compilerOptions.removeComments) {
                    return;
                }
                var leadingComments;
                if (isEmittedNode) {
                    leadingComments = getLeadingCommentsToEmit(node);
                }
                else {
                    // 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
                    if (node.pos === 0) {
                        leadingComments = ts.filter(getLeadingCommentsToEmit(node), isTripleSlashComment);
                    }
                }
                ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
                // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
                ts.emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
            }
            function emitTrailingComments(node) {
                if (compilerOptions.removeComments) {
                    return;
                }
                // Emit the trailing comments only if the parent's end doesn't match
                var trailingComments = getTrailingCommentsToEmit(node);
                // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
                ts.emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
            }
            /**
             * Emit trailing comments at the position. The term trailing comment is used here to describe following comment:
             *      x, /comment1/ y
             *        ^ => pos; the function will emit "comment1" in the emitJS
             */
            function emitTrailingCommentsOfPosition(pos) {
                if (compilerOptions.removeComments) {
                    return;
                }
                var trailingComments = ts.getTrailingCommentRanges(currentText, pos);
                // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
                ts.emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
            }
            function emitLeadingCommentsOfPositionWorker(pos) {
                if (compilerOptions.removeComments) {
                    return;
                }
                var leadingComments;
                if (hasDetachedComments(pos)) {
                    // get comments without detached comments
                    leadingComments = getLeadingCommentsWithoutDetachedComments();
                }
                else {
                    // get the leading comments from the node
                    leadingComments = ts.getLeadingCommentRanges(currentText, pos);
                }
                ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
                // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
                ts.emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
            }
            function emitDetachedCommentsAndUpdateCommentsInfo(node) {
                var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, node, newLine, compilerOptions.removeComments);
                if (currentDetachedCommentInfo) {
                    if (detachedCommentsInfo) {
                        detachedCommentsInfo.push(currentDetachedCommentInfo);
                    }
                    else {
                        detachedCommentsInfo = [currentDetachedCommentInfo];
                    }
                }
            }
            function writeComment(text, lineMap, writer, comment, newLine) {
                emitPos(comment.pos);
                ts.writeCommentRange(text, lineMap, writer, comment, newLine);
                emitPos(comment.end);
            }
            function emitShebang() {
                var shebang = ts.getShebang(currentText);
                if (shebang) {
                    write(shebang);
                    writeLine();
                }
            }
            var _a, _b;
        }
        function emitFile(_a, sourceFiles, isBundledEmit) {
            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) {
                emitJavaScript(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
            }
            else {
                emitSkipped = true;
            }
            if (declarationFilePath) {
                emitSkipped = ts.writeDeclarationFile(declarationFilePath, sourceFiles, isBundledEmit, host, resolver, emitterDiagnostics) || emitSkipped;
            }
            if (!emitSkipped && emittedFilesList) {
                emittedFilesList.push(jsFilePath);
                if (sourceMapFilePath) {
                    emittedFilesList.push(sourceMapFilePath);
                }
                if (declarationFilePath) {
                    emittedFilesList.push(declarationFilePath);
                }
            }
        }
    }
    ts.emitFiles = emitFiles;
})(ts || (ts = {}));
/// <reference path="sys.ts" />
/// <reference path="emitter.ts" />
/// <reference path="core.ts" />
var ts;
(function (ts) {
    /* @internal */ ts.programTime = 0;
    /* @internal */ ts.emitTime = 0;
    /* @internal */ ts.ioReadTime = 0;
    /* @internal */ ts.ioWriteTime = 0;
    /** The version of the TypeScript compiler release */
    ts.version = "2.0.0";
    var emptyArray = [];
    var defaultTypeRoots = ["node_modules/@types"];
    function findConfigFile(searchPath, fileExists) {
        while (true) {
            var fileName = ts.combinePaths(searchPath, "tsconfig.json");
            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;
            }
            for (var i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); 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 trace(host, message) {
        host.trace(ts.formatMessage.apply(undefined, arguments));
    }
    function isTraceEnabled(compilerOptions, host) {
        return compilerOptions.traceResolution && host.trace !== undefined;
    }
    /* @internal */
    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 createResolvedModule(resolvedFileName, isExternalLibraryImport, failedLookupLocations) {
        return { resolvedModule: resolvedFileName ? { resolvedFileName: resolvedFileName, isExternalLibraryImport: isExternalLibraryImport } : undefined, failedLookupLocations: failedLookupLocations };
    }
    function moduleHasNonRelativeName(moduleName) {
        if (ts.isRootedDiskPath(moduleName)) {
            return false;
        }
        var i = moduleName.lastIndexOf("./", 1);
        var startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === 46 /* dot */);
        return !startsWithDotSlashOrDotDotSlash;
    }
    function tryReadTypesSection(packageJsonPath, baseDirectory, state) {
        var jsonContent;
        try {
            var jsonText = state.host.readFile(packageJsonPath);
            jsonContent = jsonText ? JSON.parse(jsonText) : {};
        }
        catch (e) {
            // gracefully handle if readFile fails or returns not JSON
            jsonContent = {};
        }
        var typesFile;
        var fieldName;
        // first try to read content of 'typings' section (backward compatibility)
        if (jsonContent.typings) {
            if (typeof jsonContent.typings === "string") {
                fieldName = "typings";
                typesFile = jsonContent.typings;
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, "typings", typeof jsonContent.typings);
                }
            }
        }
        // then read 'types'
        if (!typesFile && jsonContent.types) {
            if (typeof jsonContent.types === "string") {
                fieldName = "types";
                typesFile = jsonContent.types;
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, "types", typeof jsonContent.types);
                }
            }
        }
        if (typesFile) {
            var typesFilePath = ts.normalizePath(ts.combinePaths(baseDirectory, typesFile));
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, typesFile, typesFilePath);
            }
            return typesFilePath;
        }
        // Use the main module for inferring types if no types package specified and the allowJs is set
        if (state.compilerOptions.allowJs && jsonContent.main && typeof jsonContent.main === "string") {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0, jsonContent.main);
            }
            var mainFilePath = ts.normalizePath(ts.combinePaths(baseDirectory, jsonContent.main));
            return mainFilePath;
        }
        return undefined;
    }
    var typeReferenceExtensions = [".d.ts"];
    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) {
            return undefined;
        }
        return ts.map(defaultTypeRoots, function (d) { return ts.combinePaths(currentDirectory, d); });
    }
    /**
     * @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,
            skipTsx: true,
            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 = [];
        // Check primary library paths
        if (typeRoots && typeRoots.length) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
            }
            var primarySearchPaths = typeRoots;
            for (var _i = 0, primarySearchPaths_1 = primarySearchPaths; _i < primarySearchPaths_1.length; _i++) {
                var typeRoot = primarySearchPaths_1[_i];
                var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName);
                var candidateDirectory = ts.getDirectoryPath(candidate);
                var resolvedFile_1 = loadNodeModuleFromDirectory(typeReferenceExtensions, candidate, failedLookupLocations, !directoryProbablyExists(candidateDirectory, host), moduleResolutionState);
                if (resolvedFile_1) {
                    if (traceEnabled) {
                        trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile_1, true);
                    }
                    return {
                        resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolvedFile_1 },
                        failedLookupLocations: failedLookupLocations
                    };
                }
            }
        }
        else {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
            }
        }
        var resolvedFile;
        var initialLocationForSecondaryLookup;
        if (containingFile) {
            initialLocationForSecondaryLookup = 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);
            }
            resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState);
            if (traceEnabled) {
                if (resolvedFile) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, false);
                }
                else {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
                }
            }
        }
        else {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder);
            }
        }
        return {
            resolvedTypeReferenceDirective: resolvedFile
                ? { primary: false, resolvedFileName: resolvedFile }
                : undefined,
            failedLookupLocations: failedLookupLocations
        };
    }
    ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective;
    function resolveModuleName(moduleName, containingFile, compilerOptions, host) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
        }
        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]);
            }
        }
        var result;
        switch (moduleResolution) {
            case ts.ModuleResolutionKind.NodeJs:
                result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host);
                break;
            case ts.ModuleResolutionKind.Classic:
                result = classicNameResolver(moduleName, containingFile, compilerOptions, host);
                break;
        }
        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(moduleName, containingDirectory, loader, failedLookupLocations, supportedExtensions, state) {
        if (moduleHasNonRelativeName(moduleName)) {
            return tryLoadModuleUsingBaseUrl(moduleName, loader, failedLookupLocations, supportedExtensions, state);
        }
        else {
            return tryLoadModuleUsingRootDirs(moduleName, containingDirectory, loader, failedLookupLocations, supportedExtensions, state);
        }
    }
    function tryLoadModuleUsingRootDirs(moduleName, containingDirectory, loader, failedLookupLocations, supportedExtensions, 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(candidate, supportedExtensions, 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(candidate_1, supportedExtensions, 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(moduleName, loader, failedLookupLocations, supportedExtensions, 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 = matchPatternOrExact(ts.getKeys(state.compilerOptions.paths), moduleName);
        }
        if (matchedPattern) {
            var matchedStar = typeof matchedPattern === "string" ? undefined : matchedText(matchedPattern, moduleName);
            var matchedPatternText = typeof matchedPattern === "string" ? matchedPattern : patternText(matchedPattern);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
            }
            for (var _i = 0, _a = state.compilerOptions.paths[matchedPatternText]; _i < _a.length; _i++) {
                var subst = _a[_i];
                var path = matchedStar ? subst.replace("*", matchedStar) : 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);
                }
                var resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
                if (resolvedFileName) {
                    return resolvedFileName;
                }
            }
            return undefined;
        }
        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(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
        }
    }
    /**
     * 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);
    }
    function patternText(_a) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return prefix + "*" + suffix;
    }
    /**
     * Given that candidate matches pattern, returns the text matching the '*'.
     * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
     */
    function matchedText(pattern, candidate) {
        ts.Debug.assert(isPatternMatch(pattern, candidate));
        return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
    }
    /** Return the object corresponding to the best pattern to match `candidate`. */
    /* @internal */
    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 &&
            ts.startsWith(candidate, prefix) &&
            ts.endsWith(candidate, suffix);
    }
    /* @internal */
    function tryParsePattern(pattern) {
        // This should be verified outside of here and a proper error thrown.
        ts.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 nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host) {
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var supportedExtensions = ts.getSupportedExtensions(compilerOptions);
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, skipTsx: false };
        var resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, supportedExtensions, state);
        var isExternalLibraryImport = false;
        if (!resolvedFileName) {
            if (moduleHasNonRelativeName(moduleName)) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
                }
                resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state);
                isExternalLibraryImport = resolvedFileName !== undefined;
            }
            else {
                var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
                resolvedFileName = nodeLoadModuleByRelativeName(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
            }
        }
        if (resolvedFileName && host.realpath) {
            var originalFileName = resolvedFileName;
            resolvedFileName = ts.normalizePath(host.realpath(resolvedFileName));
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, originalFileName, resolvedFileName);
            }
        }
        return createResolvedModule(resolvedFileName, isExternalLibraryImport, failedLookupLocations);
    }
    ts.nodeModuleNameResolver = nodeModuleNameResolver;
    function nodeLoadModuleByRelativeName(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state) {
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0, candidate);
        }
        var resolvedFileName = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state);
        return resolvedFileName || loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, onlyRecordFailures, state);
    }
    /* @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;
    /**
     * @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(candidate, extensions, failedLookupLocation, onlyRecordFailures, state) {
        // First try to keep/add an extension: importing "./foo.ts" can be matched by a file "./foo.ts", and "./foo" by "./foo.d.ts"
        var resolvedByAddingOrKeepingExtension = loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, onlyRecordFailures, state);
        if (resolvedByAddingOrKeepingExtension) {
            return resolvedByAddingOrKeepingExtension;
        }
        // Then 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 loadModuleFromFileWorker(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state);
        }
    }
    function loadModuleFromFileWorker(candidate, extensions, failedLookupLocation, 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);
            }
        }
        return ts.forEach(extensions, tryLoad);
        function tryLoad(ext) {
            if (state.skipTsx && ts.isJsxOrTsxExtension(ext)) {
                return undefined;
            }
            var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
            if (!onlyRecordFailures && 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);
                }
                failedLookupLocation.push(fileName);
                return undefined;
            }
        }
    }
    function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocation, onlyRecordFailures, state) {
        var packageJsonPath = ts.combinePaths(candidate, "package.json");
        var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
        if (directoryExists && state.host.fileExists(packageJsonPath)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath);
            }
            var typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
            if (typesFile) {
                var result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(ts.getDirectoryPath(typesFile), state.host), state);
                if (result) {
                    return result;
                }
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.package_json_does_not_have_types_field);
                }
            }
        }
        else {
            if (state.traceEnabled) {
                trace(state.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
            failedLookupLocation.push(packageJsonPath);
        }
        return loadModuleFromFile(ts.combinePaths(candidate, "index"), extensions, failedLookupLocation, !directoryExists, state);
    }
    function loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state) {
        var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
        var nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
        var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName));
        var supportedExtensions = ts.getSupportedExtensions(state.compilerOptions);
        var result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
        if (result) {
            return result;
        }
        result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
        if (result) {
            return result;
        }
    }
    function loadModuleFromNodeModules(moduleName, directory, failedLookupLocations, state) {
        directory = ts.normalizeSlashes(directory);
        while (true) {
            var baseName = ts.getBaseFileName(directory);
            if (baseName !== "node_modules") {
                // Try to load source from the package
                var packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
                if (packageResult && ts.hasTypeScriptFileExtension(packageResult)) {
                    // Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
                    return packageResult;
                }
                else {
                    // Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
                    var typesResult = loadModuleFromNodeModulesFolder(ts.combinePaths("@types", moduleName), directory, failedLookupLocations, state);
                    if (typesResult || packageResult) {
                        return typesResult || packageResult;
                    }
                }
            }
            var parentPath = ts.getDirectoryPath(directory);
            if (parentPath === directory) {
                break;
            }
            directory = parentPath;
        }
        return undefined;
    }
    function classicNameResolver(moduleName, containingFile, compilerOptions, host) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, skipTsx: !compilerOptions.jsx };
        var failedLookupLocations = [];
        var supportedExtensions = ts.getSupportedExtensions(compilerOptions);
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
        if (resolvedFileName) {
            return createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/ false, failedLookupLocations);
        }
        var referencedSourceFile;
        if (moduleHasNonRelativeName(moduleName)) {
            while (true) {
                var searchName = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
                referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
                if (referencedSourceFile) {
                    break;
                }
                var parentPath = ts.getDirectoryPath(containingDirectory);
                if (parentPath === containingDirectory) {
                    break;
                }
                containingDirectory = parentPath;
            }
        }
        else {
            var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
            referencedSourceFile = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
        }
        return referencedSourceFile
            ? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations: failedLookupLocations }
            : { resolvedModule: undefined, failedLookupLocations: failedLookupLocations };
    }
    ts.classicNameResolver = classicNameResolver;
    /* @internal */
    ts.defaultInitCompilerOptions = {
        module: ts.ModuleKind.CommonJS,
        target: 1 /* ES5 */,
        noImplicitAny: false,
        sourceMap: false
    };
    function createCompilerHost(options, setParentNodes) {
        var existingDirectories = {};
        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();
        }
        // returned by CScript sys environment
        var unsupportedFileEncodingErrorCode = -2147024809;
        function getSourceFile(fileName, languageVersion, onError) {
            var text;
            try {
                var start = new Date().getTime();
                text = ts.sys.readFile(fileName, options.charset);
                ts.ioReadTime += new Date().getTime() - start;
            }
            catch (e) {
                if (onError) {
                    onError(e.number === unsupportedFileEncodingErrorCode
                        ? ts.createCompilerDiagnostic(ts.Diagnostics.Unsupported_file_encoding).messageText
                        : e.message);
                }
                text = "";
            }
            return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
        }
        function directoryExists(directoryPath) {
            if (ts.hasProperty(existingDirectories, directoryPath)) {
                return true;
            }
            if (ts.sys.directoryExists(directoryPath)) {
                existingDirectories[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 = {};
            }
            var hash = ts.sys.createHash(data);
            var mtimeBefore = ts.sys.getModifiedTime(fileName);
            if (mtimeBefore && ts.hasProperty(outputFingerprints, fileName)) {
                var fingerprint = outputFingerprints[fileName];
                // If output has not been changed, and the file has no external modification
                if (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[fileName] = {
                hash: hash,
                byteOrderMark: writeByteOrderMark,
                mtime: mtimeAfter
            };
        }
        function writeFile(fileName, data, writeByteOrderMark, onError) {
            try {
                var start = new Date().getTime();
                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.ioWriteTime += new Date().getTime() - start;
            }
            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); },
            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) {
            diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
        }
        return ts.sortAndDeduplicateDiagnostics(diagnostics);
    }
    ts.getPreEmitDiagnostics = getPreEmitDiagnostics;
    function flattenDiagnosticMessageText(messageText, newLine) {
        if (typeof messageText === "string") {
            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 = {};
        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
            var name_34 = names_1[_i];
            var result = void 0;
            if (ts.hasProperty(cache, name_34)) {
                result = cache[name_34];
            }
            else {
                result = loader(name_34, containingFile);
                cache[name_34] = result;
            }
            resolutions.push(result);
        }
        return resolutions;
    }
    function getInferredTypesRoot(options, rootFiles, host) {
        return computeCommonSourceDirectoryOfFilenames(rootFiles, host.getCurrentDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    /**
      * Given a set of options and a set of root files, 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, rootFiles, 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)) {
                        result = result.concat(host.getDirectories(root));
                    }
                }
            }
        }
        return result;
    }
    ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames;
    function createProgram(rootNames, options, host, oldProgram) {
        var program;
        var files = [];
        var commonSourceDirectory;
        var diagnosticsProducingTypeChecker;
        var noDiagnosticsTypeChecker;
        var classifiableNames;
        var resolvedTypeReferenceDirectives = {};
        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 maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2;
        var currentNodeModulesJsDepth = 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 = {};
        // Track source files that are JavaScript files found by searching under node_modules, as these shouldn't be compiled.
        var sourceFilesFoundSearchingNodeModules = {};
        var start = new Date().getTime();
        host = host || createCompilerHost(options);
        var skipDefaultLib = options.noLib;
        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.createFileMap(getCanonicalFileName);
        var resolveModuleNamesWorker;
        if (host.resolveModuleNames) {
            resolveModuleNamesWorker = function (moduleNames, containingFile) { return host.resolveModuleNames(moduleNames, containingFile); };
        }
        else {
            var loader_1 = function (moduleName, containingFile) { return resolveModuleName(moduleName, containingFile, options, host).resolvedModule; };
            resolveModuleNamesWorker = function (moduleNames, containingFile) { return loadWithLocalCache(moduleNames, containingFile, loader_1); };
        }
        var resolveTypeReferenceDirectiveNamesWorker;
        if (host.resolveTypeReferenceDirectives) {
            resolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile) { return host.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile); };
        }
        else {
            var loader_2 = function (typesRef, containingFile) { return resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; };
            resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(typeReferenceDirectiveNames, containingFile, loader_2); };
        }
        var filesByName = ts.createFileMap();
        // stores 'filename -> file association' ignoring case
        // used to track cases when two file names differ only in casing
        var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createFileMap(function (fileName) { return fileName.toLowerCase(); }) : undefined;
        if (!tryReuseStructureFromOldProgram()) {
            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 = getAutomaticTypeDirectiveNames(options, rootNames, host);
            if (typeReferences) {
                var inferredRoot = getInferredTypesRoot(options, rootNames, host);
                var containingFilename = ts.combinePaths(inferredRoot, "__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(host.getDefaultLibFileName(options), /*isDefaultLib*/ true);
                }
                else {
                    var libDirectory_1 = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(host.getDefaultLibFileName(options));
                    ts.forEach(options.lib, function (libFileName) {
                        processRootFile(ts.combinePaths(libDirectory_1, libFileName), /*isDefaultLib*/ true);
                    });
                }
            }
        }
        // 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; },
            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; }
        };
        verifyCompilerOptions();
        ts.programTime += new Date().getTime() - start;
        return program;
        function getCommonSourceDirectory() {
            if (typeof commonSourceDirectory === "undefined") {
                if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
                    // If a rootDir is specified and is valid use it as the commonSourceDirectory
                    commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
                }
                else {
                    commonSourceDirectory = computeCommonSourceDirectory(files);
                }
                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 = {};
                for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
                    var sourceFile = files_2[_i];
                    ts.copyMap(sourceFile.classifiableNames, classifiableNames);
                }
            }
            return classifiableNames;
        }
        function tryReuseStructureFromOldProgram() {
            if (!oldProgram) {
                return false;
            }
            // 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 ((oldOptions.module !== options.module) ||
                (oldOptions.moduleResolution !== options.moduleResolution) ||
                (oldOptions.noResolve !== options.noResolve) ||
                (oldOptions.target !== options.target) ||
                (oldOptions.noLib !== options.noLib) ||
                (oldOptions.jsx !== options.jsx) ||
                (oldOptions.allowJs !== options.allowJs) ||
                (oldOptions.rootDir !== options.rootDir) ||
                (oldOptions.configFilePath !== options.configFilePath) ||
                (oldOptions.baseUrl !== options.baseUrl) ||
                (oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
                !ts.arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
                !ts.arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
                !ts.mapIsEqualTo(oldOptions.paths, options.paths)) {
                return false;
            }
            ts.Debug.assert(!oldProgram.structureIsReused);
            // there is an old program, check if we can reuse its structure
            var oldRootNames = oldProgram.getRootFileNames();
            if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) {
                return false;
            }
            if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) {
                return false;
            }
            // check if program source files has changed in the way that can affect structure of the program
            var newSourceFiles = [];
            var filePaths = [];
            var modifiedSourceFiles = [];
            for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) {
                var oldSourceFile = _a[_i];
                var newSourceFile = host.getSourceFileByPath
                    ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target)
                    : host.getSourceFile(oldSourceFile.fileName, options.target);
                if (!newSourceFile) {
                    return false;
                }
                newSourceFile.path = oldSourceFile.path;
                filePaths.push(newSourceFile.path);
                if (oldSourceFile !== newSourceFile) {
                    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
                        return false;
                    }
                    // check tripleslash references
                    if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
                        // tripleslash references has changed
                        return false;
                    }
                    // check imports and module augmentations
                    collectExternalModuleReferences(newSourceFile);
                    if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
                        // imports has changed
                        return false;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
                        // moduleAugmentations has changed
                        return false;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'types' references has changed
                        return false;
                    }
                    var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
                    if (resolveModuleNamesWorker) {
                        var moduleNames = ts.map(ts.concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
                        var resolutions = resolveModuleNamesWorker(moduleNames, newSourceFilePath);
                        // ensure that module resolution results are still correct
                        var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo);
                        if (resolutionsChanged) {
                            return false;
                        }
                    }
                    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) {
                            return false;
                        }
                    }
                    // pass the cache of module/types resolutions from the old source file
                    newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
                    newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
                    modifiedSourceFiles.push(newSourceFile);
                }
                else {
                    // file has no changes - use it as is
                    newSourceFile = oldSourceFile;
                }
                // if file has passed all checks it should be safe to reuse it
                newSourceFiles.push(newSourceFile);
            }
            // update fileName -> file mapping
            for (var i = 0, len = newSourceFiles.length; i < len; i++) {
                filesByName.set(filePaths[i], newSourceFiles[i]);
            }
            files = newSourceFiles;
            fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
            for (var _b = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _b < modifiedSourceFiles_1.length; _b++) {
                var modifiedFile = modifiedSourceFiles_1[_b];
                fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
            }
            resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
            oldProgram.structureIsReused = true;
            return true;
        }
        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: function (file) { return !!ts.lookUp(sourceFilesFoundSearchingNodeModules, file.path); },
                writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }),
                isEmitBlocked: isEmitBlocked
            };
        }
        function getDiagnosticsProducingTypeChecker() {
            return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true));
        }
        function getTypeChecker() {
            return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false));
        }
        function emit(sourceFile, writeFileCallback, cancellationToken) {
            var _this = this;
            return runWithCancellationToken(function () { return emitWorker(_this, sourceFile, writeFileCallback, cancellationToken); });
        }
        function isEmitBlocked(emitFileName) {
            return hasEmitBlockingDiagnostics.contains(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName));
        }
        function emitWorker(program, sourceFile, writeFileCallback, cancellationToken) {
            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);
            var start = new Date().getTime();
            var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile);
            ts.emitTime += new Date().getTime() - start;
            return emitResult;
        }
        function getSourceFile(fileName) {
            return getSourceFileByPath(ts.toPath(fileName, currentDirectory, getCanonicalFileName));
        }
        function getSourceFileByPath(path) {
            return filesByName.get(path);
        }
        function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
            if (sourceFile) {
                return getDiagnostics(sourceFile, cancellationToken);
            }
            var allDiagnostics = [];
            ts.forEach(program.getSourceFiles(), function (sourceFile) {
                if (cancellationToken) {
                    cancellationToken.throwIfCancellationRequested();
                }
                ts.addRange(allDiagnostics, getDiagnostics(sourceFile, cancellationToken));
            });
            return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        }
        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, cancellationToken) {
            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 runWithCancellationToken(function () {
                var typeChecker = getDiagnosticsProducingTypeChecker();
                ts.Debug.assert(!!sourceFile.bindDiagnostics);
                var bindDiagnostics = sourceFile.bindDiagnostics;
                // For JavaScript files, we don't want to report the normal typescript semantic errors.
                // Instead, we just report errors for using TypeScript-only constructs from within a
                // JavaScript file.
                var checkDiagnostics = ts.isSourceFileJavaScript(sourceFile) ?
                    getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) :
                    typeChecker.getDiagnostics(sourceFile, cancellationToken);
                var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
                var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
                return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
            });
        }
        function getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                var diagnostics = [];
                walk(sourceFile);
                return diagnostics;
                function walk(node) {
                    if (!node) {
                        return false;
                    }
                    switch (node.kind) {
                        case 229 /* ImportEqualsDeclaration */:
                            diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_a_ts_file));
                            return true;
                        case 235 /* ExportAssignment */:
                            if (node.isExportEquals) {
                                diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_a_ts_file));
                                return true;
                            }
                            break;
                        case 221 /* ClassDeclaration */:
                            var classDeclaration = node;
                            if (checkModifiers(classDeclaration.modifiers) ||
                                checkTypeParameters(classDeclaration.typeParameters)) {
                                return true;
                            }
                            break;
                        case 251 /* HeritageClause */:
                            var heritageClause = node;
                            if (heritageClause.token === 106 /* ImplementsKeyword */) {
                                diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
                                return true;
                            }
                            break;
                        case 222 /* InterfaceDeclaration */:
                            diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
                            return true;
                        case 225 /* ModuleDeclaration */:
                            diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
                            return true;
                        case 223 /* TypeAliasDeclaration */:
                            diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
                            return true;
                        case 147 /* MethodDeclaration */:
                        case 146 /* MethodSignature */:
                        case 148 /* Constructor */:
                        case 149 /* GetAccessor */:
                        case 150 /* SetAccessor */:
                        case 179 /* FunctionExpression */:
                        case 220 /* FunctionDeclaration */:
                        case 180 /* ArrowFunction */:
                        case 220 /* FunctionDeclaration */:
                            var functionDeclaration = node;
                            if (checkModifiers(functionDeclaration.modifiers) ||
                                checkTypeParameters(functionDeclaration.typeParameters) ||
                                checkTypeAnnotation(functionDeclaration.type)) {
                                return true;
                            }
                            break;
                        case 200 /* VariableStatement */:
                            var variableStatement = node;
                            if (checkModifiers(variableStatement.modifiers)) {
                                return true;
                            }
                            break;
                        case 218 /* VariableDeclaration */:
                            var variableDeclaration = node;
                            if (checkTypeAnnotation(variableDeclaration.type)) {
                                return true;
                            }
                            break;
                        case 174 /* CallExpression */:
                        case 175 /* NewExpression */:
                            var expression = node;
                            if (expression.typeArguments && expression.typeArguments.length > 0) {
                                var start_2 = expression.typeArguments.pos;
                                diagnostics.push(ts.createFileDiagnostic(sourceFile, start_2, expression.typeArguments.end - start_2, ts.Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
                                return true;
                            }
                            break;
                        case 142 /* Parameter */:
                            var parameter = node;
                            if (parameter.modifiers) {
                                var start_3 = parameter.modifiers.pos;
                                diagnostics.push(ts.createFileDiagnostic(sourceFile, start_3, parameter.modifiers.end - start_3, ts.Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
                                return true;
                            }
                            if (parameter.questionToken) {
                                diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
                                return true;
                            }
                            if (parameter.type) {
                                diagnostics.push(ts.createDiagnosticForNode(parameter.type, ts.Diagnostics.types_can_only_be_used_in_a_ts_file));
                                return true;
                            }
                            break;
                        case 145 /* PropertyDeclaration */:
                            var propertyDeclaration = node;
                            if (propertyDeclaration.modifiers) {
                                for (var _i = 0, _a = propertyDeclaration.modifiers; _i < _a.length; _i++) {
                                    var modifier = _a[_i];
                                    if (modifier.kind !== 113 /* StaticKeyword */) {
                                        diagnostics.push(ts.createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
                                        return true;
                                    }
                                }
                            }
                            if (checkTypeAnnotation(node.type)) {
                                return true;
                            }
                            break;
                        case 224 /* EnumDeclaration */:
                            diagnostics.push(ts.createDiagnosticForNode(node, ts.Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
                            return true;
                        case 177 /* TypeAssertionExpression */:
                            var typeAssertionExpression = node;
                            diagnostics.push(ts.createDiagnosticForNode(typeAssertionExpression.type, ts.Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
                            return true;
                        case 143 /* Decorator */:
                            if (!options.experimentalDecorators) {
                                diagnostics.push(ts.createDiagnosticForNode(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));
                            }
                            return true;
                    }
                    return ts.forEachChild(node, walk);
                }
                function checkTypeParameters(typeParameters) {
                    if (typeParameters) {
                        var start_4 = typeParameters.pos;
                        diagnostics.push(ts.createFileDiagnostic(sourceFile, start_4, typeParameters.end - start_4, ts.Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
                        return true;
                    }
                    return false;
                }
                function checkTypeAnnotation(type) {
                    if (type) {
                        diagnostics.push(ts.createDiagnosticForNode(type, ts.Diagnostics.types_can_only_be_used_in_a_ts_file));
                        return true;
                    }
                    return false;
                }
                function checkModifiers(modifiers) {
                    if (modifiers) {
                        for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
                            var modifier = modifiers_1[_i];
                            switch (modifier.kind) {
                                case 112 /* PublicKeyword */:
                                case 110 /* PrivateKeyword */:
                                case 111 /* ProtectedKeyword */:
                                case 128 /* ReadonlyKeyword */:
                                case 122 /* DeclareKeyword */:
                                    diagnostics.push(ts.createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind)));
                                    return true;
                                // These are all legal modifiers.
                                case 113 /* StaticKeyword */:
                                case 82 /* ExportKeyword */:
                                case 74 /* ConstKeyword */:
                                case 77 /* DefaultKeyword */:
                                case 115 /* AbstractKeyword */:
                            }
                        }
                    }
                    return false;
                }
            });
        }
        function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
                // Don't actually write any files since we're just getting diagnostics.
                var writeFile = function () { };
                return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
            });
        }
        function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
            return ts.isDeclarationFile(sourceFile) ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
        }
        function getOptionsDiagnostics() {
            var allDiagnostics = [];
            ts.addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics());
            ts.addRange(allDiagnostics, programDiagnostics.getGlobalDiagnostics());
            return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        }
        function getGlobalDiagnostics() {
            var allDiagnostics = [];
            ts.addRange(allDiagnostics, getDiagnosticsProducingTypeChecker().getGlobalDiagnostics());
            return ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        }
        function hasExtension(fileName) {
            return ts.getBaseFileName(fileName).indexOf(".") >= 0;
        }
        function processRootFile(fileName, isDefaultLib) {
            processSourceFile(ts.normalizePath(fileName), isDefaultLib, /*isReference*/ true);
        }
        function fileReferenceIsEqualTo(a, b) {
            return a.fileName === b.fileName;
        }
        function moduleNameIsEqualTo(a, b) {
            return a.text === b.text;
        }
        function getTextOfLiteral(literal) {
            return literal.text;
        }
        function collectExternalModuleReferences(file) {
            if (file.imports) {
                return;
            }
            var isJavaScriptFile = ts.isSourceFileJavaScript(file);
            var isExternalModuleFile = ts.isExternalModule(file);
            var imports;
            var moduleAugmentations;
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                collectModuleReferences(node, /*inAmbientModule*/ false);
                if (isJavaScriptFile) {
                    collectRequireCalls(node);
                }
            }
            file.imports = imports || emptyArray;
            file.moduleAugmentations = moduleAugmentations || emptyArray;
            return;
            function collectModuleReferences(node, inAmbientModule) {
                switch (node.kind) {
                    case 230 /* ImportDeclaration */:
                    case 229 /* ImportEqualsDeclaration */:
                    case 236 /* ExportDeclaration */:
                        var moduleNameExpr = ts.getExternalModuleName(node);
                        if (!moduleNameExpr || moduleNameExpr.kind !== 9 /* StringLiteral */) {
                            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 225 /* ModuleDeclaration */:
                        if (ts.isAmbientModule(node) && (inAmbientModule || node.flags & 2 /* Ambient */ || ts.isDeclarationFile(file))) {
                            var moduleName = node.name;
                            // 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(moduleName.text))) {
                                (moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
                            }
                            else if (!inAmbientModule) {
                                // 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 collectRequireCalls(node) {
                if (ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
                    (imports || (imports = [])).push(node.arguments[0]);
                }
                else {
                    ts.forEachChild(node, collectRequireCalls);
                }
            }
        }
        /**
          * 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration)
          */
        function processSourceFile(fileName, isDefaultLib, isReference, refFile, refPos, refEnd) {
            var diagnosticArgument;
            var diagnostic;
            if (hasExtension(fileName)) {
                if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensions, function (extension) { return ts.fileExtensionIs(host.getCanonicalFileName(fileName), extension); })) {
                    diagnostic = ts.Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1;
                    diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"];
                }
                else if (!findSourceFile(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd)) {
                    diagnostic = ts.Diagnostics.File_0_not_found;
                    diagnosticArgument = [fileName];
                }
                else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
                    diagnostic = ts.Diagnostics.A_file_cannot_have_a_reference_to_itself;
                    diagnosticArgument = [fileName];
                }
            }
            else {
                var nonTsFile = options.allowNonTsExtensions && findSourceFile(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd);
                if (!nonTsFile) {
                    if (options.allowNonTsExtensions) {
                        diagnostic = ts.Diagnostics.File_0_not_found;
                        diagnosticArgument = [fileName];
                    }
                    else if (!ts.forEach(supportedExtensions, function (extension) { return findSourceFile(fileName + extension, ts.toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd); })) {
                        diagnostic = ts.Diagnostics.File_0_not_found;
                        fileName += ".ts";
                        diagnosticArgument = [fileName];
                    }
                }
            }
            if (diagnostic) {
                if (refFile !== undefined && refEnd !== undefined && refPos !== undefined) {
                    fileProcessingDiagnostics.add(ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, diagnostic].concat(diagnosticArgument)));
                }
                else {
                    fileProcessingDiagnostics.add(ts.createCompilerDiagnostic.apply(void 0, [diagnostic].concat(diagnosticArgument)));
                }
            }
        }
        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));
            }
        }
        // Get source file from normalized fileName
        function findSourceFile(fileName, path, isDefaultLib, isReference, refFile, refPos, refEnd) {
            if (filesByName.contains(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);
                }
                // See if we need to reprocess the imports due to prior skipped imports
                if (file_1 && ts.lookUp(modulesWithElidedImports, file_1.path)) {
                    if (currentNodeModulesJsDepth < maxNodeModulesJsDepth) {
                        modulesWithElidedImports[file_1.path] = false;
                        processImportedModules(file_1, ts.getDirectoryPath(fileName));
                    }
                }
                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));
                }
            });
            filesByName.set(path, file);
            if (file) {
                file.path = path;
                if (host.useCaseSensitiveFileNames()) {
                    // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
                    var existingFile = filesByNameIgnoreCase.get(path);
                    if (existingFile) {
                        reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
                    }
                    else {
                        filesByNameIgnoreCase.set(path, file);
                    }
                }
                skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
                var basePath = ts.getDirectoryPath(fileName);
                if (!options.noResolve) {
                    processReferencedFiles(file, basePath, isDefaultLib);
                    processTypeReferenceDirectives(file);
                }
                // always process imported modules to record module name resolutions
                processImportedModules(file, basePath);
                if (isDefaultLib) {
                    files.unshift(file);
                }
                else {
                    files.push(file);
                }
            }
            return file;
        }
        function processReferencedFiles(file, basePath, isDefaultLib) {
            ts.forEach(file.referencedFiles, function (ref) {
                var referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
                processSourceFile(referencedFileName, isDefaultLib, /*isReference*/ true, file, ref.pos, ref.end);
            });
        }
        function processTypeReferenceDirectives(file) {
            var typeDirectives = ts.map(file.typeReferenceDirectives, function (l) { return l.fileName; });
            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
                ts.setResolvedTypeReferenceDirective(file, ref.fileName, resolvedTypeReferenceDirective);
                processTypeReferenceDirective(ref.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[typeReferenceDirective];
            if (previousResolution && previousResolution.primary) {
                return;
            }
            var saveResolution = true;
            if (resolvedTypeReferenceDirective) {
                if (resolvedTypeReferenceDirective.primary) {
                    // resolved from the primary path
                    processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, 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) {
                        var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
                        if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) {
                            fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Conflicting_library_definitions_for_0_found_at_1_and_2_Copy_the_correct_file_to_the_typings_folder_to_resolve_this_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, /*isReference*/ true, refFile, refPos, refEnd);
                    }
                }
            }
            else {
                fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective));
            }
            if (saveResolution) {
                resolvedTypeReferenceDirectives[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, basePath) {
            collectExternalModuleReferences(file);
            if (file.imports.length || file.moduleAugmentations.length) {
                file.resolvedModules = {};
                var moduleNames = ts.map(ts.concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
                var resolutions = resolveModuleNamesWorker(moduleNames, ts.getNormalizedAbsolutePath(file.fileName, currentDirectory));
                for (var i = 0; i < moduleNames.length; i++) {
                    var resolution = resolutions[i];
                    ts.setResolvedModule(file, moduleNames[i], resolution);
                    var resolvedPath = resolution ? ts.toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName) : undefined;
                    // 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 isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport;
                    var isJsFileFromNodeModules = isFromNodeModulesSearch && ts.hasJavaScriptFileExtension(resolution.resolvedFileName);
                    if (isFromNodeModulesSearch) {
                        sourceFilesFoundSearchingNodeModules[resolvedPath] = true;
                    }
                    if (isJsFileFromNodeModules) {
                        currentNodeModulesJsDepth++;
                    }
                    var elideImport = isJsFileFromNodeModules && currentNodeModulesJsDepth > maxNodeModulesJsDepth;
                    var shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport;
                    if (elideImport) {
                        modulesWithElidedImports[file.path] = true;
                    }
                    else if (shouldAddFile) {
                        findSourceFile(resolution.resolvedFileName, resolvedPath, 
                        /*isDefaultLib*/ false, /*isReference*/ false, file, ts.skipTrivia(file.text, file.imports[i].pos), file.imports[i].end);
                    }
                    if (isJsFileFromNodeModules) {
                        currentNodeModulesJsDepth--;
                    }
                }
            }
            else {
                // no imports - drop cached module resolutions
                file.resolvedModules = undefined;
            }
            return;
        }
        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 (!ts.isDeclarationFile(sourceFile)) {
                        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) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules"));
                }
                if (options.noEmitOnError) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules"));
                }
                if (options.out) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"));
                }
                if (options.outFile) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"));
                }
            }
            if (options.inlineSourceMap) {
                if (options.sourceMap) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"));
                }
                if (options.mapRoot) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"));
                }
            }
            if (options.paths && options.baseUrl === undefined) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option));
            }
            if (options.paths) {
                for (var key in options.paths) {
                    if (!ts.hasProperty(options.paths, key)) {
                        continue;
                    }
                    if (!hasZeroOrOneAsteriskCharacter(key)) {
                        programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key));
                    }
                    if (ts.isArray(options.paths[key])) {
                        for (var _i = 0, _a = options.paths[key]; _i < _a.length; _i++) {
                            var subst = _a[_i];
                            var typeOfSubst = typeof subst;
                            if (typeOfSubst === "string") {
                                if (!hasZeroOrOneAsteriskCharacter(subst)) {
                                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key));
                                }
                            }
                            else {
                                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst));
                            }
                        }
                    }
                    else {
                        programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key));
                    }
                }
            }
            if (!options.sourceMap && !options.inlineSourceMap) {
                if (options.inlineSources) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources"));
                }
                if (options.sourceRoot) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot"));
                }
            }
            if (options.out && options.outFile) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"));
            }
            if (options.mapRoot && !options.sourceMap) {
                // Error to specify --mapRoot without --sourcemap
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"));
            }
            if (options.declarationDir) {
                if (!options.declaration) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration"));
                }
                if (options.out || options.outFile) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile"));
                }
            }
            if (options.lib && options.noLib) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
            }
            var languageVersion = options.target || 0 /* ES3 */;
            var outFile = options.outFile || options.out;
            var firstExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) ? f : undefined; });
            if (options.isolatedModules) {
                if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES6 */) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
                }
                var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !ts.isDeclarationFile(f) ? f : undefined; });
                if (firstNonExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
                }
            }
            else if (firstExternalModuleSourceFile && languageVersion < 2 /* ES6 */ && options.module === ts.ModuleKind.None) {
                // We cannot use createDiagnosticFromNode because nodes do not have parents yet
                var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
                programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.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)) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
                }
                else if (options.module === undefined && firstExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
                    programDiagnostics.add(ts.createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.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 ||
                options.sourceRoot ||
                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; })) {
                    programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
                }
            }
            if (!options.noEmit && options.allowJs && options.declaration) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
            }
            if (options.emitDecoratorMetadata &&
                !options.experimentalDecorators) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
            }
            if (options.reactNamespace && !ts.isIdentifier(options.reactNamespace, languageVersion)) {
                programDiagnostics.add(ts.createCompilerDiagnostic(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.createFileMap(!host.useCaseSensitiveFileNames() ? function (key) { return key.toLocaleLowerCase(); } : undefined);
                ts.forEachExpectedEmitFile(emitHost, function (emitFileNames, sourceFiles, isBundledEmit) {
                    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 = ts.toPath(emitFileName, currentDirectory, getCanonicalFileName);
                    // Report error if the output overwrites input file
                    if (filesByName.contains(emitFilePath)) {
                        createEmitBlockingDiagnostics(emitFileName, emitFilePath, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
                    }
                    // Report error if multiple files write into same file
                    if (emitFilesSeen.contains(emitFilePath)) {
                        // Already seen the same emit file - report error
                        createEmitBlockingDiagnostics(emitFileName, emitFilePath, ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
                    }
                    else {
                        emitFilesSeen.set(emitFilePath, true);
                    }
                }
            }
        }
        function createEmitBlockingDiagnostics(emitFileName, emitFilePath, message) {
            hasEmitBlockingDiagnostics.set(ts.toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
            programDiagnostics.add(ts.createCompilerDiagnostic(message, emitFileName));
        }
    }
    ts.createProgram = createProgram;
})(ts || (ts = {}));
/// <reference path="sys.ts"/>
/// <reference path="types.ts"/>
/// <reference path="core.ts"/>
/// <reference path="diagnosticInformationMap.generated.ts"/>
/// <reference path="scanner.ts"/>
var ts;
(function (ts) {
    /* @internal */
    ts.optionDeclarations = [
        {
            name: "charset",
            type: "string"
        },
        {
            name: "declaration",
            shortName: "d",
            type: "boolean",
            description: ts.Diagnostics.Generates_corresponding_d_ts_file
        },
        {
            name: "declarationDir",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY
        },
        {
            name: "diagnostics",
            type: "boolean"
        },
        {
            name: "emitBOM",
            type: "boolean"
        },
        {
            name: "help",
            shortName: "h",
            type: "boolean",
            description: ts.Diagnostics.Print_this_message
        },
        {
            name: "help",
            shortName: "?",
            type: "boolean"
        },
        {
            name: "init",
            type: "boolean",
            description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file
        },
        {
            name: "inlineSourceMap",
            type: "boolean"
        },
        {
            name: "inlineSources",
            type: "boolean"
        },
        {
            name: "jsx",
            type: {
                "preserve": 1 /* Preserve */,
                "react": 2 /* React */
            },
            paramType: ts.Diagnostics.KIND,
            description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react
        },
        {
            name: "reactNamespace",
            type: "string",
            description: ts.Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit
        },
        {
            name: "listFiles",
            type: "boolean"
        },
        {
            name: "locale",
            type: "string"
        },
        {
            name: "mapRoot",
            type: "string",
            isFilePath: true,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
            paramType: ts.Diagnostics.LOCATION
        },
        {
            name: "module",
            shortName: "m",
            type: {
                "none": ts.ModuleKind.None,
                "commonjs": ts.ModuleKind.CommonJS,
                "amd": ts.ModuleKind.AMD,
                "system": ts.ModuleKind.System,
                "umd": ts.ModuleKind.UMD,
                "es6": ts.ModuleKind.ES6,
                "es2015": ts.ModuleKind.ES2015
            },
            description: ts.Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
            paramType: ts.Diagnostics.KIND
        },
        {
            name: "newLine",
            type: {
                "crlf": 0 /* CarriageReturnLineFeed */,
                "lf": 1 /* LineFeed */
            },
            description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
            paramType: ts.Diagnostics.NEWLINE
        },
        {
            name: "noEmit",
            type: "boolean",
            description: ts.Diagnostics.Do_not_emit_outputs
        },
        {
            name: "noEmitHelpers",
            type: "boolean"
        },
        {
            name: "noEmitOnError",
            type: "boolean",
            description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported
        },
        {
            name: "noImplicitAny",
            type: "boolean",
            description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type
        },
        {
            name: "noImplicitThis",
            type: "boolean",
            description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type
        },
        {
            name: "noUnusedLocals",
            type: "boolean",
            description: ts.Diagnostics.Report_Errors_on_Unused_Locals
        },
        {
            name: "noUnusedParameters",
            type: "boolean",
            description: ts.Diagnostics.Report_Errors_on_Unused_Parameters
        },
        {
            name: "noLib",
            type: "boolean"
        },
        {
            name: "noResolve",
            type: "boolean"
        },
        {
            name: "skipDefaultLibCheck",
            type: "boolean"
        },
        {
            name: "skipLibCheck",
            type: "boolean",
            description: ts.Diagnostics.Skip_type_checking_of_declaration_files
        },
        {
            name: "out",
            type: "string",
            isFilePath: false,
            // for correct behaviour, please use outFile
            paramType: ts.Diagnostics.FILE
        },
        {
            name: "outFile",
            type: "string",
            isFilePath: true,
            description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file,
            paramType: ts.Diagnostics.FILE
        },
        {
            name: "outDir",
            type: "string",
            isFilePath: true,
            description: ts.Diagnostics.Redirect_output_structure_to_the_directory,
            paramType: ts.Diagnostics.DIRECTORY
        },
        {
            name: "preserveConstEnums",
            type: "boolean",
            description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
        },
        {
            name: "pretty",
            description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental,
            type: "boolean"
        },
        {
            name: "project",
            shortName: "p",
            type: "string",
            isFilePath: true,
            description: ts.Diagnostics.Compile_the_project_in_the_given_directory,
            paramType: ts.Diagnostics.DIRECTORY
        },
        {
            name: "removeComments",
            type: "boolean",
            description: ts.Diagnostics.Do_not_emit_comments_to_output
        },
        {
            name: "rootDir",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir
        },
        {
            name: "isolatedModules",
            type: "boolean"
        },
        {
            name: "sourceMap",
            type: "boolean",
            description: ts.Diagnostics.Generates_corresponding_map_file
        },
        {
            name: "sourceRoot",
            type: "string",
            isFilePath: true,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
            paramType: ts.Diagnostics.LOCATION
        },
        {
            name: "suppressExcessPropertyErrors",
            type: "boolean",
            description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals,
            experimental: true
        },
        {
            name: "suppressImplicitAnyIndexErrors",
            type: "boolean",
            description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures
        },
        {
            name: "stripInternal",
            type: "boolean",
            description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
            experimental: true
        },
        {
            name: "target",
            shortName: "t",
            type: {
                "es3": 0 /* ES3 */,
                "es5": 1 /* ES5 */,
                "es6": 2 /* ES6 */,
                "es2015": 2 /* ES2015 */
            },
            description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
            paramType: ts.Diagnostics.VERSION
        },
        {
            name: "version",
            shortName: "v",
            type: "boolean",
            description: ts.Diagnostics.Print_the_compiler_s_version
        },
        {
            name: "watch",
            shortName: "w",
            type: "boolean",
            description: ts.Diagnostics.Watch_input_files
        },
        {
            name: "experimentalDecorators",
            type: "boolean",
            description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators
        },
        {
            name: "emitDecoratorMetadata",
            type: "boolean",
            experimental: true,
            description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
        },
        {
            name: "moduleResolution",
            type: {
                "node": ts.ModuleResolutionKind.NodeJs,
                "classic": ts.ModuleResolutionKind.Classic
            },
            description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6
        },
        {
            name: "allowUnusedLabels",
            type: "boolean",
            description: ts.Diagnostics.Do_not_report_errors_on_unused_labels
        },
        {
            name: "noImplicitReturns",
            type: "boolean",
            description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
        },
        {
            name: "noFallthroughCasesInSwitch",
            type: "boolean",
            description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
        },
        {
            name: "allowUnreachableCode",
            type: "boolean",
            description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code
        },
        {
            name: "forceConsistentCasingInFileNames",
            type: "boolean",
            description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
        },
        {
            name: "baseUrl",
            type: "string",
            isFilePath: true,
            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
        },
        {
            // 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
            }
        },
        {
            name: "typeRoots",
            type: "list",
            element: {
                name: "typeRoots",
                type: "string",
                isFilePath: true
            }
        },
        {
            name: "types",
            type: "list",
            element: {
                name: "types",
                type: "string"
            },
            description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation
        },
        {
            name: "traceResolution",
            type: "boolean",
            description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process
        },
        {
            name: "allowJs",
            type: "boolean",
            description: ts.Diagnostics.Allow_javascript_files_to_be_compiled
        },
        {
            name: "allowSyntheticDefaultImports",
            type: "boolean",
            description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
        },
        {
            name: "noImplicitUseStrict",
            type: "boolean",
            description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output
        },
        {
            name: "maxNodeModuleJsDepth",
            type: "number",
            description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
        },
        {
            name: "listEmittedFiles",
            type: "boolean"
        },
        {
            name: "lib",
            type: "list",
            element: {
                name: "lib",
                type: {
                    // 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",
                    // Host only
                    "dom": "lib.dom.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"
                }
            },
            description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
        },
        {
            name: "disableSizeLimit",
            type: "boolean"
        },
        {
            name: "strictNullChecks",
            type: "boolean",
            description: ts.Diagnostics.Enable_strict_null_checks
        }
    ];
    /* @internal */
    ts.typingOptionDeclarations = [
        {
            name: "enableAutoDiscovery",
            type: "boolean"
        },
        {
            name: "include",
            type: "list",
            element: {
                name: "include",
                type: "string"
            }
        },
        {
            name: "exclude",
            type: "list",
            element: {
                name: "exclude",
                type: "string"
            }
        }
    ];
    var optionNameMapCache;
    /* @internal */
    function getOptionNameMap() {
        if (optionNameMapCache) {
            return optionNameMapCache;
        }
        var optionNameMap = {};
        var shortOptionNames = {};
        ts.forEach(ts.optionDeclarations, function (option) {
            optionNameMap[option.name.toLowerCase()] = option;
            if (option.shortName) {
                shortOptionNames[option.shortName] = option.name;
            }
        });
        optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames };
        return optionNameMapCache;
    }
    ts.getOptionNameMap = getOptionNameMap;
    /* @internal */
    function createCompilerDiagnosticForInvalidCustomType(opt) {
        var namesOfType = [];
        ts.forEachKey(opt.type, function (key) {
            namesOfType.push(" '" + key + "'");
        });
        return ts.createCompilerDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType);
    }
    ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType;
    /* @internal */
    function parseCustomTypeOption(opt, value, errors) {
        var key = trimString((value || "")).toLowerCase();
        var map = opt.type;
        if (ts.hasProperty(map, key)) {
            return map[key];
        }
        else {
            errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
        }
    }
    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;
    /* @internal */
    function parseCommandLine(commandLine, readFile) {
        var options = {};
        var fileNames = [];
        var errors = [];
        var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames;
        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 */) {
                    s = s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1).toLowerCase();
                    // Try to translate short option names to their full equivalents.
                    if (ts.hasProperty(shortOptionNames, s)) {
                        s = shortOptionNames[s];
                    }
                    if (ts.hasProperty(optionNameMap, s)) {
                        var opt = optionNameMap[s];
                        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":
                                    options[opt.name] = true;
                                    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;
    /**
      * Read tsconfig.json file
      * @param fileName The path to the config file
      */
    function readConfigFile(fileName, readFile) {
        var text = "";
        try {
            text = readFile(fileName);
        }
        catch (e) {
            return { error: ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message) };
        }
        return parseConfigFileTextToJson(fileName, text);
    }
    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) {
        try {
            var jsonTextWithoutComments = removeComments(jsonText);
            return { config: /\S/.test(jsonTextWithoutComments) ? JSON.parse(jsonTextWithoutComments) : {} };
        }
        catch (e) {
            return { error: ts.createCompilerDiagnostic(ts.Diagnostics.Failed_to_parse_file_0_Colon_1, fileName, e.message) };
        }
    }
    ts.parseConfigFileTextToJson = parseConfigFileTextToJson;
    /**
     * Remove the comments from a json like text.
     * Comments can be single line comments (starting with # or //) or multiline comments using / * * /
     *
     * This method replace comment content by whitespace rather than completely remove them to keep positions in json parsing error reporting accurate.
     */
    function removeComments(jsonText) {
        var output = "";
        var scanner = ts.createScanner(1 /* ES5 */, /* skipTrivia */ false, 0 /* Standard */, jsonText);
        var token;
        while ((token = scanner.scan()) !== 1 /* EndOfFileToken */) {
            switch (token) {
                case 2 /* SingleLineCommentTrivia */:
                case 3 /* MultiLineCommentTrivia */:
                    // replace comments with whitespace to preserve original character positions
                    output += scanner.getTokenText().replace(/\S/g, " ");
                    break;
                default:
                    output += scanner.getTokenText();
                    break;
            }
        }
        return output;
    }
    // Skip over any minified JavaScript files (ending in ".min.js")
    // Skip over dotted files and folders as well
    var ignoreFileNamePattern = /(\.min\.js$)|([\\/]\.[\w.])/;
    /**
      * 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) {
        if (existingOptions === void 0) { existingOptions = {}; }
        var errors = [];
        var compilerOptions = convertCompilerOptionsFromJsonWorker(json["compilerOptions"], basePath, errors, configFileName);
        var options = ts.extend(existingOptions, compilerOptions);
        var typingOptions = convertTypingOptionsFromJsonWorker(json["typingOptions"], basePath, errors, configFileName);
        options.configFilePath = configFileName;
        var _a = getFileNames(errors), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories;
        return {
            options: options,
            fileNames: fileNames,
            typingOptions: typingOptions,
            raw: json,
            errors: errors,
            wildcardDirectories: wildcardDirectories
        };
        function getFileNames(errors) {
            var fileNames;
            if (ts.hasProperty(json, "files")) {
                if (ts.isArray(json["files"])) {
                    fileNames = json["files"];
                }
                else {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"));
                }
            }
            var includeSpecs;
            if (ts.hasProperty(json, "include")) {
                if (ts.isArray(json["include"])) {
                    includeSpecs = json["include"];
                }
                else {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array"));
                }
            }
            var excludeSpecs;
            if (ts.hasProperty(json, "exclude")) {
                if (ts.isArray(json["exclude"])) {
                    excludeSpecs = json["exclude"];
                }
                else {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array"));
                }
            }
            else if (ts.hasProperty(json, "excludes")) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
            }
            else {
                // By default, exclude common package folders
                excludeSpecs = ["node_modules", "bower_components", "jspm_packages"];
            }
            // Always exclude the output directory unless explicitly included
            var outDir = json["compilerOptions"] && json["compilerOptions"]["outDir"];
            if (outDir) {
                excludeSpecs.push(outDir);
            }
            if (fileNames === undefined && includeSpecs === undefined) {
                includeSpecs = ["**/*"];
            }
            return matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors);
        }
    }
    ts.parseJsonConfigFileContent = parseJsonConfigFileContent;
    function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson;
    function convertTypingOptionsFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertTypingOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertTypingOptionsFromJson = convertTypingOptionsFromJson;
    function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = ts.getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true } : {};
        convertOptionsFromJson(ts.optionDeclarations, jsonOptions, basePath, options, ts.Diagnostics.Unknown_compiler_option_0, errors);
        return options;
    }
    function convertTypingOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = ts.getBaseFileName(configFileName) === "jsconfig.json"
            ? { enableAutoDiscovery: true, include: [], exclude: [] }
            : { enableAutoDiscovery: false, include: [], exclude: [] };
        convertOptionsFromJson(ts.typingOptionDeclarations, jsonOptions, basePath, options, ts.Diagnostics.Unknown_typing_option_0, errors);
        return options;
    }
    function convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, defaultOptions, diagnosticMessage, errors) {
        if (!jsonOptions) {
            return;
        }
        var optionNameMap = ts.arrayToMap(optionDeclarations, function (opt) { return opt.name; });
        for (var id in jsonOptions) {
            if (ts.hasProperty(optionNameMap, id)) {
                var opt = optionNameMap[id];
                defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
            }
            else {
                errors.push(ts.createCompilerDiagnostic(diagnosticMessage, id));
            }
        }
    }
    function convertJsonOption(opt, value, basePath, errors) {
        var optType = opt.type;
        var expectedType = typeof optType === "string" ? optType : "string";
        if (optType === "list" && ts.isArray(value)) {
            return convertJsonOptionOfListType(opt, value, basePath, errors);
        }
        else if (typeof value === expectedType) {
            if (typeof optType !== "string") {
                return convertJsonOptionOfCustomType(opt, value, errors);
            }
            else {
                if (opt.isFilePath) {
                    value = ts.normalizePath(ts.combinePaths(basePath, value));
                    if (value === "") {
                        value = ".";
                    }
                }
            }
            return value;
        }
        else {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, expectedType));
        }
    }
    function convertJsonOptionOfCustomType(opt, value, errors) {
        var key = value.toLowerCase();
        if (ts.hasProperty(opt.type, key)) {
            return opt.type[key];
        }
        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 fileNames The literal file names to include.
     * @param include The wildcard file specifications to include.
     * @param exclude 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(fileNames, include, exclude, basePath, options, host, errors) {
        basePath = ts.normalizePath(basePath);
        // 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.
        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 = {};
        // 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 = {};
        if (include) {
            include = validateSpecs(include, errors, /*allowTrailingRecursion*/ false);
        }
        if (exclude) {
            exclude = validateSpecs(exclude, errors, /*allowTrailingRecursion*/ true);
        }
        // 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(include, exclude, basePath, host.useCaseSensitiveFileNames);
        // 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);
        // Literal files are always included verbatim. An "include" or "exclude" specification cannot
        // remove a literal file.
        if (fileNames) {
            for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
                var fileName = fileNames_1[_i];
                var file = ts.combinePaths(basePath, fileName);
                literalFileMap[keyMapper(file)] = file;
            }
        }
        if (include && include.length > 0) {
            for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensions, exclude, include); _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;
                }
                if (ignoreFileNamePattern.test(file)) {
                    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 (!ts.hasProperty(literalFileMap, key) && !ts.hasProperty(wildcardFileMap, key)) {
                    wildcardFileMap[key] = file;
                }
            }
        }
        var literalFiles = ts.reduceProperties(literalFileMap, addFileToOutput, []);
        var wildcardFiles = ts.reduceProperties(wildcardFileMap, addFileToOutput, []);
        wildcardFiles.sort(host.useCaseSensitiveFileNames ? ts.compareStrings : ts.compareStringsCaseInsensitive);
        return {
            fileNames: literalFiles.concat(wildcardFiles),
            wildcardDirectories: wildcardDirectories
        };
    }
    function validateSpecs(specs, errors, allowTrailingRecursion) {
        var validSpecs = [];
        for (var _i = 0, specs_2 = specs; _i < specs_2.length; _i++) {
            var spec = specs_2[_i];
            if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec));
            }
            else if (invalidMultipleRecursionPatterns.test(spec)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec));
            }
            else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec));
            }
            else {
                validSpecs.push(spec);
            }
        }
        return validSpecs;
    }
    /**
     * 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
        //
        // 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 name_35 = ts.normalizePath(ts.combinePaths(path, file));
                if (excludeRegex && excludeRegex.test(name_35)) {
                    continue;
                }
                var match = wildcardDirectoryPattern.exec(name_35);
                if (match) {
                    var key = useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase();
                    var flags = watchRecursivePattern.test(name_35) ? 1 /* Recursive */ : 0 /* None */;
                    var existingFlags = ts.getProperty(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;
    }
    /**
     * 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);
        for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) {
            var higherPriorityExtension = extensions[i];
            var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension));
            if (ts.hasProperty(literalFiles, higherPriorityPath) || ts.hasProperty(wildcardFiles, 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);
        for (var i = nextExtensionPriority; i < extensions.length; i++) {
            var lowerPriorityExtension = extensions[i];
            var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension));
            delete wildcardFiles[lowerPriorityPath];
        }
    }
    /**
     * Adds a file to an array of files.
     *
     * @param output The output array.
     * @param file The file path.
     */
    function addFileToOutput(output, file) {
        output.push(file);
        return output;
    }
    /**
     * 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();
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var OutliningElementsCollector;
    (function (OutliningElementsCollector) {
        function collectElements(sourceFile) {
            var elements = [];
            var collapseText = "...";
            function addOutliningSpan(hintSpanNode, startElement, endElement, autoCollapse) {
                if (hintSpanNode && startElement && endElement) {
                    var span = {
                        textSpan: ts.createTextSpanFromBounds(startElement.pos, endElement.end),
                        hintSpan: ts.createTextSpanFromBounds(hintSpanNode.getStart(), hintSpanNode.end),
                        bannerText: collapseText,
                        autoCollapse: autoCollapse
                    };
                    elements.push(span);
                }
            }
            function addOutliningSpanComments(commentSpan, autoCollapse) {
                if (commentSpan) {
                    var span = {
                        textSpan: ts.createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
                        hintSpan: ts.createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
                        bannerText: collapseText,
                        autoCollapse: autoCollapse
                    };
                    elements.push(span);
                }
            }
            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_2 = comments; _i < comments_2.length; _i++) {
                        var currentComment = comments_2[_i];
                        // 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 = {
                        pos: start,
                        end: end,
                        kind: 2 /* SingleLineCommentTrivia */
                    };
                    addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
                }
            }
            function autoCollapse(node) {
                return ts.isFunctionBlock(node) && node.parent.kind !== 180 /* ArrowFunction */;
            }
            var depth = 0;
            var maxDepth = 20;
            function walk(n) {
                if (depth > maxDepth) {
                    return;
                }
                if (ts.isDeclaration(n)) {
                    addOutliningForLeadingCommentsForNode(n);
                }
                switch (n.kind) {
                    case 199 /* Block */:
                        if (!ts.isFunctionBlock(n)) {
                            var parent_15 = n.parent;
                            var openBrace = ts.findChildOfKind(n, 15 /* OpenBraceToken */, sourceFile);
                            var closeBrace = ts.findChildOfKind(n, 16 /* 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_15.kind === 204 /* DoStatement */ ||
                                parent_15.kind === 207 /* ForInStatement */ ||
                                parent_15.kind === 208 /* ForOfStatement */ ||
                                parent_15.kind === 206 /* ForStatement */ ||
                                parent_15.kind === 203 /* IfStatement */ ||
                                parent_15.kind === 205 /* WhileStatement */ ||
                                parent_15.kind === 212 /* WithStatement */ ||
                                parent_15.kind === 252 /* CatchClause */) {
                                addOutliningSpan(parent_15, openBrace, closeBrace, autoCollapse(n));
                                break;
                            }
                            if (parent_15.kind === 216 /* TryStatement */) {
                                // Could be the try-block, or the finally-block.
                                var tryStatement = parent_15;
                                if (tryStatement.tryBlock === n) {
                                    addOutliningSpan(parent_15, openBrace, closeBrace, autoCollapse(n));
                                    break;
                                }
                                else if (tryStatement.finallyBlock === n) {
                                    var finallyKeyword = ts.findChildOfKind(tryStatement, 85 /* FinallyKeyword */, sourceFile);
                                    if (finallyKeyword) {
                                        addOutliningSpan(finallyKeyword, openBrace, closeBrace, autoCollapse(n));
                                        break;
                                    }
                                }
                            }
                            // 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 = ts.createTextSpanFromBounds(n.getStart(), n.end);
                            elements.push({
                                textSpan: span,
                                hintSpan: span,
                                bannerText: collapseText,
                                autoCollapse: autoCollapse(n)
                            });
                            break;
                        }
                    // Fallthrough.
                    case 226 /* ModuleBlock */: {
                        var openBrace = ts.findChildOfKind(n, 15 /* OpenBraceToken */, sourceFile);
                        var closeBrace = ts.findChildOfKind(n, 16 /* CloseBraceToken */, sourceFile);
                        addOutliningSpan(n.parent, openBrace, closeBrace, autoCollapse(n));
                        break;
                    }
                    case 221 /* ClassDeclaration */:
                    case 222 /* InterfaceDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 171 /* ObjectLiteralExpression */:
                    case 227 /* CaseBlock */: {
                        var openBrace = ts.findChildOfKind(n, 15 /* OpenBraceToken */, sourceFile);
                        var closeBrace = ts.findChildOfKind(n, 16 /* CloseBraceToken */, sourceFile);
                        addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n));
                        break;
                    }
                    case 170 /* ArrayLiteralExpression */:
                        var openBracket = ts.findChildOfKind(n, 19 /* OpenBracketToken */, sourceFile);
                        var closeBracket = ts.findChildOfKind(n, 20 /* CloseBracketToken */, sourceFile);
                        addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n));
                        break;
                }
                depth++;
                ts.forEachChild(n, walk);
                depth--;
            }
            walk(sourceFile);
            return elements;
        }
        OutliningElementsCollector.collectElements = collectElements;
    })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var NavigateTo;
    (function (NavigateTo) {
        function getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount) {
            var patternMatcher = ts.createPatternMatcher(searchValue);
            var rawItems = [];
            // This means "compare in a case insensitive manner."
            var baseSensitivity = { sensitivity: "base" };
            // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
            ts.forEach(program.getSourceFiles(), function (sourceFile) {
                cancellationToken.throwIfCancellationRequested();
                var nameToDeclarations = sourceFile.getNamedDeclarations();
                for (var name_36 in nameToDeclarations) {
                    var declarations = ts.getProperty(nameToDeclarations, name_36);
                    if (declarations) {
                        // 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_36);
                        if (!matches) {
                            continue;
                        }
                        for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) {
                            var declaration = declarations_7[_i];
                            // It was a match!  If the pattern has dots in it, then also see if the
                            // declaration container matches as well.
                            if (patternMatcher.patternContainsDots) {
                                var containers = getContainers(declaration);
                                if (!containers) {
                                    return undefined;
                                }
                                matches = patternMatcher.getMatches(containers, name_36);
                                if (!matches) {
                                    continue;
                                }
                            }
                            var fileName = sourceFile.fileName;
                            var matchKind = bestMatchKind(matches);
                            rawItems.push({ name: name_36, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration });
                        }
                    }
                }
            });
            // Remove imports when the imported declaration is already in the list and has the same name.
            rawItems = ts.filter(rawItems, function (item) {
                var decl = item.declaration;
                if (decl.kind === 231 /* ImportClause */ || decl.kind === 234 /* ImportSpecifier */ || decl.kind === 229 /* ImportEqualsDeclaration */) {
                    var importer = checker.getSymbolAtLocation(decl.name);
                    var imported = checker.getAliasedSymbol(importer);
                    return importer.name !== imported.name;
                }
                else {
                    return true;
                }
            });
            rawItems.sort(compareNavigateToItems);
            if (maxResultCount !== undefined) {
                rawItems = rawItems.slice(0, maxResultCount);
            }
            var items = ts.map(rawItems, createNavigateToItem);
            return items;
            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_1 = matches; _i < matches_1.length; _i++) {
                    var match = matches_1[_i];
                    if (!match.isCaseSensitive) {
                        return false;
                    }
                }
                return true;
            }
            function getTextOfIdentifierOrLiteral(node) {
                if (node) {
                    if (node.kind === 69 /* Identifier */ ||
                        node.kind === 9 /* StringLiteral */ ||
                        node.kind === 8 /* NumericLiteral */) {
                        return node.text;
                    }
                }
                return undefined;
            }
            function tryAddSingleDeclarationName(declaration, containers) {
                if (declaration && declaration.name) {
                    var text = getTextOfIdentifierOrLiteral(declaration.name);
                    if (text !== undefined) {
                        containers.unshift(text);
                    }
                    else if (declaration.name.kind === 140 /* ComputedPropertyName */) {
                        return tryAddComputedPropertyName(declaration.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 = getTextOfIdentifierOrLiteral(expression);
                if (text !== undefined) {
                    if (includeLastPortion) {
                        containers.unshift(text);
                    }
                    return true;
                }
                if (expression.kind === 172 /* 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.
                if (declaration.name.kind === 140 /* ComputedPropertyName */) {
                    if (!tryAddComputedPropertyName(declaration.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_2 = matches; _i < matches_2.length; _i++) {
                    var match = matches_2[_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 ||
                    i1.name.localeCompare(i2.name, undefined, baseSensitivity) ||
                    i1.name.localeCompare(i2.name);
            }
            function createNavigateToItem(rawItem) {
                var declaration = rawItem.declaration;
                var container = ts.getContainerNode(declaration);
                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.createTextSpanFromBounds(declaration.getStart(), declaration.getEnd()),
                    // TODO(jfreeman): What should be the containerName when the container has a computed name?
                    containerName: container && container.name ? container.name.text : "",
                    containerKind: container && container.name ? ts.getNodeKind(container) : ""
                };
            }
        }
        NavigateTo.getNavigateToItems = getNavigateToItems;
    })(NavigateTo = ts.NavigateTo || (ts.NavigateTo = {}));
})(ts || (ts = {}));
/// <reference path='services.ts' />
/* @internal */
var ts;
(function (ts) {
    var NavigationBar;
    (function (NavigationBar) {
        function getNavigationBarItems(sourceFile) {
            curSourceFile = sourceFile;
            var result = ts.map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
            curSourceFile = undefined;
            return result;
        }
        NavigationBar.getNavigationBarItems = getNavigationBarItems;
        // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
        var curSourceFile;
        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];
            }
        }
        /*
        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;
        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) {
            if (!node || ts.isToken(node)) {
                return;
            }
            switch (node.kind) {
                case 148 /* 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 147 /* MethodDeclaration */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 146 /* MethodSignature */:
                    if (!ts.hasDynamicName(node)) {
                        addNodeWithRecursiveChild(node, node.body);
                    }
                    break;
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                    if (!ts.hasDynamicName(node)) {
                        addLeafNode(node);
                    }
                    break;
                case 231 /* 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 === 232 /* NamespaceImport */) {
                            addLeafNode(namedBindings);
                        }
                        else {
                            for (var _b = 0, _c = namedBindings.elements; _b < _c.length; _b++) {
                                var element = _c[_b];
                                addLeafNode(element);
                            }
                        }
                    }
                    break;
                case 169 /* BindingElement */:
                case 218 /* VariableDeclaration */:
                    var decl = node;
                    var name_37 = decl.name;
                    if (ts.isBindingPattern(name_37)) {
                        addChildrenRecursively(name_37);
                    }
                    else if (decl.initializer && isFunctionOrClassExpression(decl.initializer)) {
                        // For `const x = function() {}`, just use the function node, not the const.
                        addChildrenRecursively(decl.initializer);
                    }
                    else {
                        addNodeWithRecursiveChild(decl, decl.initializer);
                    }
                    break;
                case 180 /* ArrowFunction */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                    addNodeWithRecursiveChild(node, node.body);
                    break;
                case 224 /* EnumDeclaration */:
                    startNode(node);
                    for (var _d = 0, _e = node.members; _d < _e.length; _d++) {
                        var member = _e[_d];
                        if (!isComputedProperty(member)) {
                            addLeafNode(member);
                        }
                    }
                    endNode();
                    break;
                case 221 /* ClassDeclaration */:
                case 192 /* ClassExpression */:
                case 222 /* InterfaceDeclaration */:
                    startNode(node);
                    for (var _f = 0, _g = node.members; _f < _g.length; _f++) {
                        var member = _g[_f];
                        addChildrenRecursively(member);
                    }
                    endNode();
                    break;
                case 225 /* ModuleDeclaration */:
                    addNodeWithRecursiveChild(node, getInteriorModule(node).body);
                    break;
                case 238 /* ExportSpecifier */:
                case 229 /* ImportEqualsDeclaration */:
                case 153 /* IndexSignature */:
                case 151 /* CallSignature */:
                case 152 /* ConstructSignature */:
                case 223 /* TypeAliasDeclaration */:
                    addLeafNode(node);
                    break;
                default:
                    if (node.jsDocComments) {
                        for (var _h = 0, _j = node.jsDocComments; _h < _j.length; _h++) {
                            var jsDocComment = _j[_h];
                            for (var _k = 0, _l = jsDocComment.tags; _k < _l.length; _k++) {
                                var tag = _l[_k];
                                if (tag.kind === 279 /* JSDocTypedefTag */) {
                                    addLeafNode(tag);
                                }
                            }
                        }
                    }
                    ts.forEachChild(node, addChildrenRecursively);
            }
        }
        /** Merge declarations of the same kind. */
        function mergeChildren(children) {
            var nameToItems = {};
            ts.filterMutate(children, function (child) {
                var decl = child.node;
                var name = decl.name && nodeText(decl.name);
                if (!name) {
                    // Anonymous items are never merged.
                    return true;
                }
                var itemsWithSameName = ts.getProperty(nameToItems, name);
                if (!itemsWithSameName) {
                    nameToItems[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[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 !== 225 /* 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 !== 225 /* 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 = localeCompareFix(name1, name2);
                return cmp !== 0 ? cmp : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
            }
            else {
                return name1 ? 1 : name2 ? -1 : navigationBarNodeKind(child1) - navigationBarNodeKind(child2);
            }
        }
        // More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
        var collator = typeof Intl === "undefined" ? undefined : new Intl.Collator();
        // Intl is missing in Safari, and node 0.10 treats "a" as greater than "B".
        var localeCompareIsCorrect = collator && collator.compare("a", "B") < 0;
        var localeCompareFix = localeCompareIsCorrect ? collator.compare : function (a, b) {
            // This isn't perfect, but it passes all of our tests.
            for (var i = 0; i < Math.min(a.length, b.length); i++) {
                var chA = a.charAt(i), chB = b.charAt(i);
                if (chA === "\"" && chB === "'") {
                    return 1;
                }
                if (chA === "'" && chB === "\"") {
                    return -1;
                }
                var cmp = chA.toLocaleLowerCase().localeCompare(chB.toLocaleLowerCase());
                if (cmp !== 0) {
                    return cmp;
                }
            }
            return a.length - b.length;
        };
        /**
         * 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 === 225 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            var decl = node;
            if (decl.name) {
                return ts.getPropertyNameForPropertyNameNode(decl.name);
            }
            switch (node.kind) {
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                case 192 /* ClassExpression */:
                    return getFunctionOrClassName(node);
                case 279 /* JSDocTypedefTag */:
                    return getJSDocTypedefTagName(node);
                default:
                    return undefined;
            }
        }
        function getItemName(node) {
            if (node.kind === 225 /* ModuleDeclaration */) {
                return getModuleName(node);
            }
            var name = node.name;
            if (name) {
                var text = nodeText(name);
                if (text.length > 0) {
                    return text;
                }
            }
            switch (node.kind) {
                case 256 /* SourceFile */:
                    var sourceFile = node;
                    return ts.isExternalModule(sourceFile)
                        ? "\"" + ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName)))) + "\""
                        : "<global>";
                case 180 /* ArrowFunction */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 221 /* ClassDeclaration */:
                case 192 /* ClassExpression */:
                    if (node.flags & 512 /* Default */) {
                        return "default";
                    }
                    return getFunctionOrClassName(node);
                case 148 /* Constructor */:
                    return "constructor";
                case 152 /* ConstructSignature */:
                    return "new()";
                case 151 /* CallSignature */:
                    return "()";
                case 153 /* IndexSignature */:
                    return "[]";
                case 279 /* 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 === 200 /* VariableStatement */) {
                    if (parentNode.declarationList.declarations.length > 0) {
                        var nameIdentifier = parentNode.declarationList.declarations[0].name;
                        if (nameIdentifier.kind === 69 /* 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 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 224 /* EnumDeclaration */:
                    case 222 /* InterfaceDeclaration */:
                    case 225 /* ModuleDeclaration */:
                    case 256 /* SourceFile */:
                    case 223 /* TypeAliasDeclaration */:
                    case 279 /* JSDocTypedefTag */:
                        return true;
                    case 148 /* Constructor */:
                    case 147 /* MethodDeclaration */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        return hasSomeImportantChild(item);
                    case 180 /* ArrowFunction */:
                    case 220 /* FunctionDeclaration */:
                    case 179 /* FunctionExpression */:
                        return isTopLevelFunctionDeclaration(item);
                    default:
                        return false;
                }
                function isTopLevelFunctionDeclaration(item) {
                    if (!item.node.body) {
                        return false;
                    }
                    switch (navigationBarNodeKind(item.parent)) {
                        case 226 /* ModuleBlock */:
                        case 256 /* SourceFile */:
                        case 147 /* MethodDeclaration */:
                        case 148 /* Constructor */:
                            return true;
                        default:
                            return hasSomeImportantChild(item);
                    }
                }
                function hasSomeImportantChild(item) {
                    return ts.forEach(item.children, function (child) {
                        var childKind = navigationBarNodeKind(child);
                        return childKind !== 218 /* VariableDeclaration */ && childKind !== 169 /* BindingElement */;
                    });
                }
            }
        }
        // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
        var emptyChildItemArray = [];
        function convertToTopLevelItem(n) {
            return {
                text: getItemName(n.node),
                kind: nodeKind(n.node),
                kindModifiers: ts.getNodeModifiers(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: nodeKind(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;
            }
        }
        // TODO: GH#9145: We should just use getNodeKind. No reason why navigationBar and navigateTo should have different behaviors.
        function nodeKind(node) {
            switch (node.kind) {
                case 256 /* SourceFile */:
                    return ts.ScriptElementKind.moduleElement;
                case 255 /* EnumMember */:
                    return ts.ScriptElementKind.memberVariableElement;
                case 218 /* VariableDeclaration */:
                case 169 /* BindingElement */:
                    var variableDeclarationNode = void 0;
                    var name_38;
                    if (node.kind === 169 /* BindingElement */) {
                        name_38 = node.name;
                        variableDeclarationNode = node;
                        // binding elements are added only for variable declarations
                        // bubble up to the containing variable declaration
                        while (variableDeclarationNode && variableDeclarationNode.kind !== 218 /* VariableDeclaration */) {
                            variableDeclarationNode = variableDeclarationNode.parent;
                        }
                        ts.Debug.assert(!!variableDeclarationNode);
                    }
                    else {
                        ts.Debug.assert(!ts.isBindingPattern(node.name));
                        variableDeclarationNode = node;
                        name_38 = node.name;
                    }
                    if (ts.isConst(variableDeclarationNode)) {
                        return ts.ScriptElementKind.constElement;
                    }
                    else if (ts.isLet(variableDeclarationNode)) {
                        return ts.ScriptElementKind.letElement;
                    }
                    else {
                        return ts.ScriptElementKind.variableElement;
                    }
                case 180 /* ArrowFunction */:
                    return ts.ScriptElementKind.functionElement;
                case 279 /* JSDocTypedefTag */:
                    return ts.ScriptElementKind.typeElement;
                default:
                    return ts.getNodeKind(node);
            }
        }
        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(moduleDeclaration.name.text);
            while (moduleDeclaration.body && moduleDeclaration.body.kind === 225 /* ModuleDeclaration */) {
                moduleDeclaration = moduleDeclaration.body;
                result.push(moduleDeclaration.name.text);
            }
            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 === 225 /* ModuleDeclaration */ ? getInteriorModule(decl.body) : decl;
        }
        function isComputedProperty(member) {
            return !member.name || member.name.kind === 140 /* ComputedPropertyName */;
        }
        function getNodeSpan(node) {
            return node.kind === 256 /* SourceFile */
                ? ts.createTextSpanFromBounds(node.getFullStart(), node.getEnd())
                : ts.createTextSpanFromBounds(node.getStart(curSourceFile), node.getEnd());
        }
        function getFunctionOrClassName(node) {
            if (node.name && ts.getFullWidth(node.name) > 0) {
                return ts.declarationNameToString(node.name);
            }
            else if (node.parent.kind === 218 /* VariableDeclaration */) {
                return ts.declarationNameToString(node.parent.name);
            }
            else if (node.parent.kind === 187 /* BinaryExpression */ &&
                node.parent.operatorToken.kind === 56 /* EqualsToken */) {
                return nodeText(node.parent.left);
            }
            else if (node.parent.kind === 253 /* PropertyAssignment */ && node.parent.name) {
                return nodeText(node.parent.name);
            }
            else if (node.flags & 512 /* Default */) {
                return "default";
            }
            else {
                return ts.isClassLike(node) ? "<class>" : "<function>";
            }
        }
        function isFunctionOrClassExpression(node) {
            return node.kind === 179 /* FunctionExpression */ || node.kind === 180 /* ArrowFunction */ || node.kind === 192 /* ClassExpression */;
        }
    })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
    (function (PatternMatchKind) {
        PatternMatchKind[PatternMatchKind["exact"] = 0] = "exact";
        PatternMatchKind[PatternMatchKind["prefix"] = 1] = "prefix";
        PatternMatchKind[PatternMatchKind["substring"] = 2] = "substring";
        PatternMatchKind[PatternMatchKind["camelCase"] = 3] = "camelCase";
    })(ts.PatternMatchKind || (ts.PatternMatchKind = {}));
    var 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 = {};
        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) {
            if (!ts.hasProperty(stringToWordSpans, word)) {
                stringToWordSpans[word] = breakIntoWordSpans(word);
            }
            return stringToWordSpans[word];
        }
        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:*/ 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 = wordSpans_1[_i];
                        if (partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ true)) {
                            return createPatternMatch(PatternMatchKind.substring, punctuationStripped, 
                            /*isCaseSensitive:*/ partStartsWith(candidate, span, 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, 2 /* 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, 2 /* 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();
    }
    function startsWith(string, search) {
        for (var i = 0, n = search.length; i < n; i++) {
            if (string.charCodeAt(i) !== search.charCodeAt(i)) {
                return false;
            }
        }
        return true;
    }
    // Assumes 'value' is already lowercase.
    function indexOfIgnoringCase(string, value) {
        for (var i = 0, n = string.length - value.length; 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, n = value.length; i < n; 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, n = identifier.length; i < n; 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 = {}));
///<reference path='services.ts' />
/* @internal */
var ts;
(function (ts) {
    var SignatureHelp;
    (function (SignatureHelp) {
        // A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression
        // or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference.
        // To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it
        // will return the generic identifier that started the expression (e.g. "foo" in "foo<any, |"). It is then up to the caller to ensure that this is a valid generic expression through
        // looking up the type. The method will also keep track of the parameter index inside the expression.
        // public static isInPartiallyWrittenTypeArgumentList(syntaxTree: TypeScript.SyntaxTree, position: number): any {
        //    let token = Syntax.findTokenOnLeft(syntaxTree.sourceUnit(), position, /*includeSkippedTokens*/ true);
        //    if (token && TypeScript.Syntax.hasAncestorOfKind(token, TypeScript.SyntaxKind.TypeParameterList)) {
        //        // We are in the wrong generic list. bail out
        //        return null;
        //    }
        //    let stack = 0;
        //    let argumentIndex = 0;
        //    whileLoop:
        //    while (token) {
        //        switch (token.kind()) {
        //            case TypeScript.SyntaxKind.LessThanToken:
        //                if (stack === 0) {
        //                    // Found the beginning of the generic argument expression
        //                    let lessThanToken = token;
        //                    token = previousToken(token, /*includeSkippedTokens*/ true);
        //                    if (!token || token.kind() !== TypeScript.SyntaxKind.IdentifierName) {
        //                        break whileLoop;
        //                    }
        //                    // Found the name, return the data
        //                    return {
        //                        genericIdentifer: token,
        //                        lessThanToken: lessThanToken,
        //                        argumentIndex: argumentIndex
        //                    };
        //                }
        //                else if (stack < 0) {
        //                    // Seen one too many less than tokens, bail out
        //                    break whileLoop;
        //                }
        //                else {
        //                    stack--;
        //                }
        //                break;
        //            case TypeScript.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
        //                stack++;
        //            // Intentional fall through
        //            case TypeScript.SyntaxKind.GreaterThanToken:
        //                stack++;
        //                break;
        //            case TypeScript.SyntaxKind.CommaToken:
        //                if (stack == 0) {
        //                    argumentIndex++;
        //                }
        //                break;
        //            case TypeScript.SyntaxKind.CloseBraceToken:
        //                // This can be object type, skip untill we find the matching open brace token
        //                let unmatchedOpenBraceTokens = 0;
        //                // Skip untill the matching open brace token
        //                token = SignatureInfoHelpers.moveBackUpTillMatchingTokenKind(token, TypeScript.SyntaxKind.CloseBraceToken, TypeScript.SyntaxKind.OpenBraceToken);
        //                if (!token) {
        //                    // No matching token was found. bail out
        //                    break whileLoop;
        //                }
        //                break;
        //            case TypeScript.SyntaxKind.EqualsGreaterThanToken:
        //                // This can be a function type or a constructor type. In either case, we want to skip the function definition
        //                token = previousToken(token, /*includeSkippedTokens*/ true);
        //                if (token && token.kind() === TypeScript.SyntaxKind.CloseParenToken) {
        //                    // Skip untill the matching open paren token
        //                    token = SignatureInfoHelpers.moveBackUpTillMatchingTokenKind(token, TypeScript.SyntaxKind.CloseParenToken, TypeScript.SyntaxKind.OpenParenToken);
        //                    if (token && token.kind() === TypeScript.SyntaxKind.GreaterThanToken) {
        //                        // Another generic type argument list, skip it\
        //                        token = SignatureInfoHelpers.moveBackUpTillMatchingTokenKind(token, TypeScript.SyntaxKind.GreaterThanToken, TypeScript.SyntaxKind.LessThanToken);
        //                    }
        //                    if (token && token.kind() === TypeScript.SyntaxKind.NewKeyword) {
        //                        // In case this was a constructor type, skip the new keyword
        //                        token = previousToken(token, /*includeSkippedTokens*/ true);
        //                    }
        //                    if (!token) {
        //                        // No matching token was found. bail out
        //                        break whileLoop;
        //                    }
        //                }
        //                else {
        //                    // This is not a function type. exit the main loop
        //                    break whileLoop;
        //                }
        //                break;
        //            case TypeScript.SyntaxKind.IdentifierName:
        //            case TypeScript.SyntaxKind.AnyKeyword:
        //            case TypeScript.SyntaxKind.NumberKeyword:
        //            case TypeScript.SyntaxKind.StringKeyword:
        //            case TypeScript.SyntaxKind.VoidKeyword:
        //            case TypeScript.SyntaxKind.BooleanKeyword:
        //            case TypeScript.SyntaxKind.DotToken:
        //            case TypeScript.SyntaxKind.OpenBracketToken:
        //            case TypeScript.SyntaxKind.CloseBracketToken:
        //                // Valid tokens in a type name. Skip.
        //                break;
        //            default:
        //                break whileLoop;
        //        }
        //        token = previousToken(token, /*includeSkippedTokens*/ true);
        //    }
        //    return null;
        // }
        // private static moveBackUpTillMatchingTokenKind(token: TypeScript.ISyntaxToken, tokenKind: TypeScript.SyntaxKind, matchingTokenKind: TypeScript.SyntaxKind): TypeScript.ISyntaxToken {
        //    if (!token || token.kind() !== tokenKind) {
        //        throw TypeScript.Errors.invalidOperation();
        //    }
        //    // Skip the current token
        //    token = previousToken(token, /*includeSkippedTokens*/ true);
        //    let stack = 0;
        //    while (token) {
        //        if (token.kind() === matchingTokenKind) {
        //            if (stack === 0) {
        //                // Found the matching token, return
        //                return token;
        //            }
        //            else if (stack < 0) {
        //                // tokens overlapped.. bail out.
        //                break;
        //            }
        //            else {
        //                stack--;
        //            }
        //        }
        //        else if (token.kind() === tokenKind) {
        //            stack++;
        //        }
        //        // Move back
        //        token = previousToken(token, /*includeSkippedTokens*/ true);
        //    }
        //    // Did not find matching token
        //    return null;
        // }
        var emptyArray = [];
        (function (ArgumentListKind) {
            ArgumentListKind[ArgumentListKind["TypeArguments"] = 0] = "TypeArguments";
            ArgumentListKind[ArgumentListKind["CallArguments"] = 1] = "CallArguments";
            ArgumentListKind[ArgumentListKind["TaggedTemplateArguments"] = 2] = "TaggedTemplateArguments";
        })(SignatureHelp.ArgumentListKind || (SignatureHelp.ArgumentListKind = {}));
        var 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);
            cancellationToken.throwIfCancellationRequested();
            // Semantic filtering of signature help
            if (!argumentInfo) {
                return undefined;
            }
            var call = argumentInfo.invocation;
            var candidates = [];
            var resolvedSignature = typeChecker.getResolvedSignature(call, candidates);
            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 !== 174 /* 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 === 69 /* Identifier */
                ? expression
                : expression.kind === 172 /* PropertyAccessExpression */
                    ? expression.name
                    : undefined;
            if (!name || !name.text) {
                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 = ts.getProperty(nameToDeclarations, name.text);
                if (declarations) {
                    for (var _b = 0, declarations_8 = declarations; _b < declarations_8.length; _b++) {
                        var declaration = declarations_8[_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 (node.parent.kind === 174 /* CallExpression */ || node.parent.kind === 175 /* NewExpression */) {
                var callExpression = node.parent;
                // There are 3 cases to handle:
                //   1. The token introduces a list, and should begin a sig 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 sig help
                //
                // The following are examples of each:
                //
                //    Case 1:
                //          foo<#T, U>(#a, b)    -> The token introduces a list, and should begin a sig 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 sig help
                // Find out if 'node' is an argument, a type argument, or neither
                if (node.kind === 25 /* LessThanToken */ ||
                    node.kind === 17 /* OpenParenToken */) {
                    // Find the list that starts right *after* the < or ( token.
                    // If the user has just opened a list, consider this item 0.
                    var list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile);
                    var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
                    ts.Debug.assert(list !== undefined);
                    return {
                        kind: isTypeArgList ? 0 /* TypeArguments */ : 1 /* CallArguments */,
                        invocation: callExpression,
                        argumentsSpan: getApplicableSpanForArguments(list, sourceFile),
                        argumentIndex: 0,
                        argumentCount: getArgumentCount(list)
                    };
                }
                // 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 paren, 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
                var listItemInfo = ts.findListItemInfo(node);
                if (listItemInfo) {
                    var list = listItemInfo.list;
                    var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
                    var argumentIndex = getArgumentIndex(list, node);
                    var argumentCount = getArgumentCount(list);
                    ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex);
                    return {
                        kind: isTypeArgList ? 0 /* TypeArguments */ : 1 /* CallArguments */,
                        invocation: callExpression,
                        argumentsSpan: getApplicableSpanForArguments(list, sourceFile),
                        argumentIndex: argumentIndex,
                        argumentCount: argumentCount
                    };
                }
                return undefined;
            }
            else if (node.kind === 11 /* NoSubstitutionTemplateLiteral */ && node.parent.kind === 176 /* 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 === 12 /* TemplateHead */ && node.parent.parent.kind === 176 /* TaggedTemplateExpression */) {
                var templateExpression = node.parent;
                var tagExpression = templateExpression.parent;
                ts.Debug.assert(templateExpression.kind === 189 /* TemplateExpression */);
                var argumentIndex = ts.isInsideTemplateLiteral(node, position) ? 0 : 1;
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            else if (node.parent.kind === 197 /* TemplateSpan */ && node.parent.parent.parent.kind === 176 /* TaggedTemplateExpression */) {
                var templateSpan = node.parent;
                var templateExpression = templateSpan.parent;
                var tagExpression = templateExpression.parent;
                ts.Debug.assert(templateExpression.kind === 189 /* TemplateExpression */);
                // If we're just after a template tail, don't show signature help.
                if (node.kind === 14 /* TemplateTail */ && !ts.isInsideTemplateLiteral(node, position)) {
                    return undefined;
                }
                var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
                var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position);
                return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile);
            }
            return undefined;
        }
        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 !== 24 /* 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, givin us an
            // arg count of 3.
            var listChildren = argumentsList.getChildren();
            var argumentCount = ts.countWhere(listChildren, function (arg) { return arg.kind !== 24 /* CommaToken */; });
            if (listChildren.length > 0 && ts.lastOrUndefined(listChildren).kind === 24 /* 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 === 11 /* NoSubstitutionTemplateLiteral */
                ? 1
                : tagExpression.template.templateSpans.length + 1;
            ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex);
            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 === 189 /* 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 !== 256 /* 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;
                }
            }
            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];
        }
        /**
         * The selectedItemIndex could be negative for several reasons.
         *     1. There are too many arguments for all of the overloads
         *     2. None of the overloads were type compatible
         * The solution here is to try to pick the best overload by picking
         * either the first one that has an appropriate number of parameters,
         * or the one with the most parameters.
         */
        function selectBestInvalidOverloadIndex(candidates, argumentCount) {
            var maxParamsSignatureIndex = -1;
            var maxParams = -1;
            for (var i = 0; i < candidates.length; i++) {
                var candidate = candidates[i];
                if (candidate.hasRestParameter || candidate.parameters.length >= argumentCount) {
                    return i;
                }
                if (candidate.parameters.length > maxParams) {
                    maxParams = candidate.parameters.length;
                    maxParamsSignatureIndex = i;
                }
            }
            return maxParamsSignatureIndex;
        }
        function createSignatureHelpItems(candidates, bestSignature, argumentListInfo, typeChecker) {
            var applicableSpan = argumentListInfo.argumentsSpan;
            var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */;
            var invocation = argumentListInfo.invocation;
            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);
                }
                if (isTypeParameterList) {
                    prefixDisplayParts.push(ts.punctuationPart(25 /* LessThanToken */));
                    var typeParameters = candidateSignature.typeParameters;
                    signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
                    suffixDisplayParts.push(ts.punctuationPart(27 /* GreaterThanToken */));
                    var parameterParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation);
                    });
                    ts.addRange(suffixDisplayParts, parameterParts);
                }
                else {
                    var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                        return typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation);
                    });
                    ts.addRange(prefixDisplayParts, typeParameterParts);
                    prefixDisplayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                    var parameters = candidateSignature.parameters;
                    signatureHelpParameters = parameters.length > 0 ? ts.map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
                    suffixDisplayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                }
                var returnTypeParts = ts.mapToDisplayParts(function (writer) {
                    return typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation);
                });
                ts.addRange(suffixDisplayParts, returnTypeParts);
                return {
                    isVariadic: candidateSignature.hasRestParameter,
                    prefixDisplayParts: prefixDisplayParts,
                    suffixDisplayParts: suffixDisplayParts,
                    separatorDisplayParts: [ts.punctuationPart(24 /* CommaToken */), ts.spacePart()],
                    parameters: signatureHelpParameters,
                    documentation: candidateSignature.getDocumentationComment()
                };
            });
            var argumentIndex = argumentListInfo.argumentIndex;
            // argumentCount is the *apparent* number of arguments.
            var argumentCount = argumentListInfo.argumentCount;
            var selectedItemIndex = candidates.indexOf(bestSignature);
            if (selectedItemIndex < 0) {
                selectedItemIndex = selectBestInvalidOverloadIndex(candidates, argumentCount);
            }
            ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex);
            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: emptyArray,
                    displayParts: displayParts,
                    isOptional: false
                };
            }
        }
    })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {}));
})(ts || (ts = {}));
// These utilities are common to multiple language service features.
/* @internal */
var ts;
(function (ts) {
    function getLineStartPositionForPosition(position, sourceFile) {
        var lineStarts = sourceFile.getLineStarts();
        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;
    function positionBelongsToNode(candidate, position, sourceFile) {
        return candidate.end > position || !isCompletedNode(candidate, sourceFile);
    }
    ts.positionBelongsToNode = positionBelongsToNode;
    function isCompletedNode(n, sourceFile) {
        if (ts.nodeIsMissing(n)) {
            return false;
        }
        switch (n.kind) {
            case 221 /* ClassDeclaration */:
            case 222 /* InterfaceDeclaration */:
            case 224 /* EnumDeclaration */:
            case 171 /* ObjectLiteralExpression */:
            case 167 /* ObjectBindingPattern */:
            case 159 /* TypeLiteral */:
            case 199 /* Block */:
            case 226 /* ModuleBlock */:
            case 227 /* CaseBlock */:
            case 233 /* NamedImports */:
            case 237 /* NamedExports */:
                return nodeEndsWith(n, 16 /* CloseBraceToken */, sourceFile);
            case 252 /* CatchClause */:
                return isCompletedNode(n.block, sourceFile);
            case 175 /* NewExpression */:
                if (!n.arguments) {
                    return true;
                }
            // fall through
            case 174 /* CallExpression */:
            case 178 /* ParenthesizedExpression */:
            case 164 /* ParenthesizedType */:
                return nodeEndsWith(n, 18 /* CloseParenToken */, sourceFile);
            case 156 /* FunctionType */:
            case 157 /* ConstructorType */:
                return isCompletedNode(n.type, sourceFile);
            case 148 /* Constructor */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
            case 220 /* FunctionDeclaration */:
            case 179 /* FunctionExpression */:
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
            case 152 /* ConstructSignature */:
            case 151 /* CallSignature */:
            case 180 /* 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, 18 /* CloseParenToken */, sourceFile);
            case 225 /* ModuleDeclaration */:
                return n.body && isCompletedNode(n.body, sourceFile);
            case 203 /* IfStatement */:
                if (n.elseStatement) {
                    return isCompletedNode(n.elseStatement, sourceFile);
                }
                return isCompletedNode(n.thenStatement, sourceFile);
            case 202 /* ExpressionStatement */:
                return isCompletedNode(n.expression, sourceFile) ||
                    hasChildOfKind(n, 23 /* SemicolonToken */);
            case 170 /* ArrayLiteralExpression */:
            case 168 /* ArrayBindingPattern */:
            case 173 /* ElementAccessExpression */:
            case 140 /* ComputedPropertyName */:
            case 161 /* TupleType */:
                return nodeEndsWith(n, 20 /* CloseBracketToken */, sourceFile);
            case 153 /* IndexSignature */:
                if (n.type) {
                    return isCompletedNode(n.type, sourceFile);
                }
                return hasChildOfKind(n, 20 /* CloseBracketToken */, sourceFile);
            case 249 /* CaseClause */:
            case 250 /* DefaultClause */:
                // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed
                return false;
            case 206 /* ForStatement */:
            case 207 /* ForInStatement */:
            case 208 /* ForOfStatement */:
            case 205 /* WhileStatement */:
                return isCompletedNode(n.statement, sourceFile);
            case 204 /* DoStatement */:
                // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
                var hasWhileKeyword = findChildOfKind(n, 104 /* WhileKeyword */, sourceFile);
                if (hasWhileKeyword) {
                    return nodeEndsWith(n, 18 /* CloseParenToken */, sourceFile);
                }
                return isCompletedNode(n.statement, sourceFile);
            case 158 /* TypeQuery */:
                return isCompletedNode(n.exprName, sourceFile);
            case 182 /* TypeOfExpression */:
            case 181 /* DeleteExpression */:
            case 183 /* VoidExpression */:
            case 190 /* YieldExpression */:
            case 191 /* SpreadElementExpression */:
                var unaryWordExpression = n;
                return isCompletedNode(unaryWordExpression.expression, sourceFile);
            case 176 /* TaggedTemplateExpression */:
                return isCompletedNode(n.template, sourceFile);
            case 189 /* TemplateExpression */:
                var lastSpan = ts.lastOrUndefined(n.templateSpans);
                return isCompletedNode(lastSpan, sourceFile);
            case 197 /* TemplateSpan */:
                return ts.nodeIsPresent(n.literal);
            case 236 /* ExportDeclaration */:
            case 230 /* ImportDeclaration */:
                return ts.nodeIsPresent(n.moduleSpecifier);
            case 185 /* PrefixUnaryExpression */:
                return isCompletedNode(n.operand, sourceFile);
            case 187 /* BinaryExpression */:
                return isCompletedNode(n.right, sourceFile);
            case 188 /* 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 = ts.lastOrUndefined(children);
            if (last.kind === expectedLastToken) {
                return true;
            }
            else if (last.kind === 23 /* 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.indexOf(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 (c.kind === 282 /* SyntaxList */ && 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) {
        if (includeJsDocComment === void 0) { includeJsDocComment = false; }
        return getTouchingToken(sourceFile, position, function (n) { return isWord(n.kind); }, includeJsDocComment);
    }
    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) {
        if (includeJsDocComment === void 0) { includeJsDocComment = false; }
        return getTouchingToken(sourceFile, position, function (n) { return isPropertyName(n.kind); }, includeJsDocComment);
    }
    ts.getTouchingPropertyName = getTouchingPropertyName;
    /** Returns the token if position is in [start, end) or if position === end and includeItemAtEndPosition(token) === true */
    function getTouchingToken(sourceFile, position, includeItemAtEndPosition, includeJsDocComment) {
        if (includeJsDocComment === void 0) { includeJsDocComment = false; }
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includeItemAtEndPosition, includeJsDocComment);
    }
    ts.getTouchingToken = getTouchingToken;
    /** Returns a token if position is in [start-of-leading-trivia, end) */
    function getTokenAtPosition(sourceFile, position, includeJsDocComment) {
        if (includeJsDocComment === void 0) { includeJsDocComment = false; }
        return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includeItemAtEndPosition*/ undefined, includeJsDocComment);
    }
    ts.getTokenAtPosition = getTokenAtPosition;
    /** Get the token whose text contains the position */
    function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includeItemAtEndPosition, includeJsDocComment) {
        if (includeJsDocComment === void 0) { includeJsDocComment = false; }
        var current = sourceFile;
        outer: while (true) {
            if (isToken(current)) {
                // exit early
                return current;
            }
            if (includeJsDocComment) {
                var jsDocChildren = ts.filter(current.getChildren(), ts.isJSDocNode);
                for (var _i = 0, jsDocChildren_1 = jsDocChildren; _i < jsDocChildren_1.length; _i++) {
                    var jsDocChild = jsDocChildren_1[_i];
                    var start = allowPositionInLeadingTrivia ? jsDocChild.getFullStart() : jsDocChild.getStart(sourceFile, includeJsDocComment);
                    if (start <= position) {
                        var end = jsDocChild.getEnd();
                        if (position < end || (position === end && jsDocChild.kind === 1 /* EndOfFileToken */)) {
                            current = jsDocChild;
                            continue outer;
                        }
                        else if (includeItemAtEndPosition && end === position) {
                            var previousToken = findPrecedingToken(position, sourceFile, jsDocChild);
                            if (previousToken && includeItemAtEndPosition(previousToken)) {
                                return previousToken;
                            }
                        }
                    }
                }
            }
            // find the child that contains 'position'
            for (var i = 0, n = current.getChildCount(sourceFile); i < n; i++) {
                var child = current.getChildAt(i);
                // all jsDocComment nodes were already visited
                if (ts.isJSDocNode(child)) {
                    continue;
                }
                var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment);
                if (start <= position) {
                    var end = child.getEnd();
                    if (position < end || (position === end && child.kind === 1 /* EndOfFileToken */)) {
                        current = child;
                        continue outer;
                    }
                    else if (includeItemAtEndPosition && end === position) {
                        var previousToken = findPrecedingToken(position, sourceFile, child);
                        if (previousToken && includeItemAtEndPosition(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);
        if (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 (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_1 = children; _i < children_1.length; _i++) {
                var child = children_1[_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;
    function findPrecedingToken(position, sourceFile, startNode) {
        return find(startNode || sourceFile);
        function findRightmostToken(n) {
            if (isToken(n) || n.kind === 244 /* JsxText */) {
                return n;
            }
            var children = n.getChildren();
            var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length);
            return candidate && findRightmostToken(candidate);
        }
        function find(n) {
            if (isToken(n) || n.kind === 244 /* JsxText */) {
                return n;
            }
            var children = n.getChildren();
            for (var i = 0, len = children.length; i < len; i++) {
                var child = children[i];
                // condition 'position < child.end' checks if child node end after the position
                // in the example below this condition will be false for 'aaaa' and 'bbbb' and true for 'ccc'
                // aaaa___bbbb___$__ccc
                // after we found child node with end after the position we check if start of the node is after the position.
                // if yes - then position is in the trivia and we need to look into the previous child to find the token in question.
                // if no - position is in the node itself so we should recurse in it.
                // NOTE: JsxText is a weird kind of node that can contain only whitespaces (since they are not counted as trivia).
                // if this is the case - then we should assume that token in question is located in previous child.
                if (position < child.end && (nodeHasTokens(child) || child.kind === 244 /* JsxText */)) {
                    var start = child.getStart(sourceFile);
                    var lookInPreviousChild = (start >= position) ||
                        (child.kind === 244 /* JsxText */ && start === child.end); // whitespace only JsxText
                    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 === 256 /* SourceFile */);
            // 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 last node that is considered as candidate for search (isCandidate(node) === true) starting from 'exclusiveStartPosition'
        function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) {
            for (var i = exclusiveStartPosition - 1; i >= 0; i--) {
                if (nodeHasTokens(children[i])) {
                    return children[i];
                }
            }
        }
    }
    ts.findPrecedingToken = findPrecedingToken;
    function isInString(sourceFile, position) {
        var previousToken = findPrecedingToken(position, sourceFile);
        if (previousToken &&
            (previousToken.kind === 9 /* StringLiteral */ || previousToken.kind === 166 /* StringLiteralType */)) {
            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;
    function isInComment(sourceFile, position) {
        return isInCommentHelper(sourceFile, position, /*predicate*/ undefined);
    }
    ts.isInComment = isInComment;
    /**
     * 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);
        if (!token) {
            return false;
        }
        if (token.kind === 244 /* JsxText */) {
            return true;
        }
        // <div>Hello |</div>
        if (token.kind === 25 /* LessThanToken */ && token.parent.kind === 244 /* JsxText */) {
            return true;
        }
        // <div> { | </div> or <div a={| </div>
        if (token.kind === 25 /* LessThanToken */ && token.parent.kind === 248 /* JsxExpression */) {
            return true;
        }
        // <div> {
        // |
        // } < /div>
        if (token && token.kind === 16 /* CloseBraceToken */ && token.parent.kind === 248 /* JsxExpression */) {
            return true;
        }
        // <div>|</div>
        if (token.kind === 25 /* LessThanToken */ && token.parent.kind === 245 /* JsxClosingElement */) {
            return true;
        }
        return false;
    }
    ts.isInsideJsxElementOrAttribute = isInsideJsxElementOrAttribute;
    function isInTemplateString(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        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 that additionally
     * satisfies predicate, and false otherwise.
     */
    function isInCommentHelper(sourceFile, position, predicate) {
        var token = getTokenAtPosition(sourceFile, position);
        if (token && position <= token.getStart(sourceFile)) {
            var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
            // The end marker of a single-line comment does not include the newline character.
            // In the following case, we are inside a comment (^ denotes the cursor position):
            //
            //    // asdf   ^\n
            //
            // But for multi-line comments, we don't want to be inside the comment in the following case:
            //
            //    /* asdf */^
            //
            // Internally, we represent the end of the comment at the newline and closing '/', respectively.
            return predicate ?
                ts.forEach(commentRanges, function (c) { return c.pos < position &&
                    (c.kind == 2 /* SingleLineCommentTrivia */ ? position <= c.end : position < c.end) &&
                    predicate(c); }) :
                ts.forEach(commentRanges, function (c) { return c.pos < position &&
                    (c.kind == 2 /* SingleLineCommentTrivia */ ? position <= c.end : position < c.end); });
        }
        return false;
    }
    ts.isInCommentHelper = isInCommentHelper;
    function hasDocComment(sourceFile, position) {
        var token = getTokenAtPosition(sourceFile, position);
        // 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;
    /**
     * Get the corresponding JSDocTag node if the position is in a jsDoc comment
     */
    function getJsDocTagAtPosition(sourceFile, position) {
        var node = ts.getTokenAtPosition(sourceFile, position);
        if (isToken(node)) {
            switch (node.kind) {
                case 102 /* VarKeyword */:
                case 108 /* LetKeyword */:
                case 74 /* ConstKeyword */:
                    // if the current token is var, let or const, skip the VariableDeclarationList
                    node = node.parent === undefined ? undefined : node.parent.parent;
                    break;
                default:
                    node = node.parent;
                    break;
            }
        }
        if (node) {
            if (node.jsDocComments) {
                for (var _i = 0, _a = node.jsDocComments; _i < _a.length; _i++) {
                    var jsDocComment = _a[_i];
                    for (var _b = 0, _c = jsDocComment.tags; _b < _c.length; _b++) {
                        var tag = _c[_b];
                        if (tag.pos <= position && position <= tag.end) {
                            return tag;
                        }
                    }
                }
            }
        }
        return undefined;
    }
    ts.getJsDocTagAtPosition = getJsDocTagAtPosition;
    function nodeHasTokens(n) {
        // If we have a token or node that has a non-zero width, it must have tokens.
        // Note, that getWidth() does not take trivia into account.
        return n.getWidth() !== 0;
    }
    function getNodeModifiers(node) {
        var flags = ts.getCombinedNodeFlags(node);
        var result = [];
        if (flags & 8 /* Private */)
            result.push(ts.ScriptElementKindModifier.privateMemberModifier);
        if (flags & 16 /* Protected */)
            result.push(ts.ScriptElementKindModifier.protectedMemberModifier);
        if (flags & 4 /* Public */)
            result.push(ts.ScriptElementKindModifier.publicMemberModifier);
        if (flags & 32 /* Static */)
            result.push(ts.ScriptElementKindModifier.staticModifier);
        if (flags & 128 /* Abstract */)
            result.push(ts.ScriptElementKindModifier.abstractModifier);
        if (flags & 1 /* Export */)
            result.push(ts.ScriptElementKindModifier.exportedModifier);
        if (ts.isInAmbientContext(node))
            result.push(ts.ScriptElementKindModifier.ambientModifier);
        return result.length > 0 ? result.join(",") : ts.ScriptElementKindModifier.none;
    }
    ts.getNodeModifiers = getNodeModifiers;
    function getTypeArgumentOrTypeParameterList(node) {
        if (node.kind === 155 /* TypeReference */ || node.kind === 174 /* CallExpression */) {
            return node.typeArguments;
        }
        if (ts.isFunctionLike(node) || node.kind === 221 /* ClassDeclaration */ || node.kind === 222 /* InterfaceDeclaration */) {
            return node.typeParameters;
        }
        return undefined;
    }
    ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList;
    function isToken(n) {
        return n.kind >= 0 /* FirstToken */ && n.kind <= 138 /* LastToken */;
    }
    ts.isToken = isToken;
    function isWord(kind) {
        return kind === 69 /* 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 === 166 /* StringLiteralType */
            || kind === 10 /* RegularExpressionLiteral */
            || ts.isTemplateLiteralKind(kind)) {
            return true;
        }
        return false;
    }
    ts.isStringOrRegularExpressionOrTemplateLiteral = isStringOrRegularExpressionOrTemplateLiteral;
    function isPunctuation(kind) {
        return 15 /* FirstPunctuation */ <= kind && kind <= 68 /* 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 112 /* PublicKeyword */:
            case 110 /* PrivateKeyword */:
            case 111 /* ProtectedKeyword */:
                return true;
        }
        return false;
    }
    ts.isAccessibilityModifier = isAccessibilityModifier;
    function compareDataObjects(dst, src) {
        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;
    function isArrayLiteralOrObjectLiteralDestructuringPattern(node) {
        if (node.kind === 170 /* ArrayLiteralExpression */ ||
            node.kind === 171 /* ObjectLiteralExpression */) {
            // [a,b,c] from:
            // [a, b, c] = someExpression;
            if (node.parent.kind === 187 /* BinaryExpression */ &&
                node.parent.left === node &&
                node.parent.operatorToken.kind === 56 /* EqualsToken */) {
                return true;
            }
            // [a, b, c] from:
            // for([a, b, c] of expression)
            if (node.parent.kind === 208 /* 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 === 253 /* PropertyAssignment */ ? node.parent.parent : node.parent)) {
                return true;
            }
        }
        return false;
    }
    ts.isArrayLiteralOrObjectLiteralDestructuringPattern = isArrayLiteralOrObjectLiteralDestructuringPattern;
})(ts || (ts = {}));
// Display-part writer helpers
/* @internal */
var ts;
(function (ts) {
    function isFirstDeclarationOfSymbolParameter(symbol) {
        return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 142 /* 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); },
            writeSymbol: writeSymbol,
            writeLine: writeLine,
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            clear: resetWriter,
            trackSymbol: function () { },
            reportInaccessibleThisError: function () { }
        };
        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), 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 & 8388608 /* Alias */) {
                return ts.SymbolDisplayPartKind.aliasName;
            }
            return ts.SymbolDisplayPartKind.text;
        }
    }
    ts.symbolPart = symbolPart;
    function displayPart(text, kind, symbol) {
        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) {
        writeDisplayParts(displayPartWriter);
        var result = displayPartWriter.displayParts();
        displayPartWriter.clear();
        return result;
    }
    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) {
        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)) {
            return location.getText();
        }
        else if (ts.isStringOrNumericLiteral(location.kind) &&
            location.parent.kind === 140 /* ComputedPropertyName */) {
            return location.text;
        }
        // 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);
        var name = typeChecker.symbolToString(localExportDefaultSymbol || symbol);
        return name;
    }
    ts.getDeclaredName = getDeclaredName;
    function isImportOrExportSpecifierName(location) {
        return location.parent &&
            (location.parent.kind === 234 /* ImportSpecifier */ || location.parent.kind === 238 /* 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) &&
            (name.charCodeAt(0) === 34 /* doubleQuote */ || name.charCodeAt(0) === 39 /* singleQuote */)) {
            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.
        var scriptKind;
        if (host && host.getScriptKind) {
            scriptKind = host.getScriptKind(fileName);
        }
        if (!scriptKind || scriptKind === 0 /* Unknown */) {
            scriptKind = ts.getScriptKindFromFileName(fileName);
        }
        return ts.ensureScriptKind(fileName, scriptKind);
    }
    ts.getScriptKind = getScriptKind;
})(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 JsTyping;
    (function (JsTyping) {
        ;
        ;
        // A map of loose file names to library names
        // that we are confident require typings
        var safeList;
        /**
         * @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 typingOptions are used to customize the typing inference process
         * @param compilerOptions are used as a source for typing inference
         */
        function discoverTypings(host, fileNames, projectRootPath, safeListPath, packageNameToTypingLocation, typingOptions, compilerOptions) {
            // A typing name to typing file path mapping
            var inferredTypings = {};
            if (!typingOptions || !typingOptions.enableAutoDiscovery) {
                return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
            }
            // Only infer typings for .js and .jsx files
            fileNames = ts.filter(ts.map(fileNames, ts.normalizePath), function (f) { return ts.scriptKindIs(f, /*LanguageServiceHost*/ undefined, 1 /* JS */, 2 /* JSX */); });
            if (!safeList) {
                var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); });
                if (result.config) {
                    safeList = result.config;
                }
                else {
                    safeList = {};
                }
                ;
            }
            var filesToWatch = [];
            // Directories to search for package.json, bower.json and other typing information
            var searchDirs = [];
            var exclude = [];
            mergeTypings(typingOptions.include);
            exclude = typingOptions.exclude || [];
            var possibleSearchDirs = ts.map(fileNames, ts.getDirectoryPath);
            if (projectRootPath !== undefined) {
                possibleSearchDirs.push(projectRootPath);
            }
            searchDirs = ts.deduplicate(possibleSearchDirs);
            for (var _i = 0, searchDirs_1 = searchDirs; _i < searchDirs_1.length; _i++) {
                var searchDir = searchDirs_1[_i];
                var packageJsonPath = ts.combinePaths(searchDir, "package.json");
                getTypingNamesFromJson(packageJsonPath, filesToWatch);
                var bowerJsonPath = ts.combinePaths(searchDir, "bower.json");
                getTypingNamesFromJson(bowerJsonPath, filesToWatch);
                var nodeModulesPath = ts.combinePaths(searchDir, "node_modules");
                getTypingNamesFromNodeModuleFolder(nodeModulesPath);
            }
            getTypingNamesFromSourceFileNames(fileNames);
            // Add the cached typing locations for inferred typings that are already installed
            for (var name_39 in packageNameToTypingLocation) {
                if (ts.hasProperty(inferredTypings, name_39) && !inferredTypings[name_39]) {
                    inferredTypings[name_39] = packageNameToTypingLocation[name_39];
                }
            }
            // Remove typings that the user has added to the exclude list
            for (var _a = 0, exclude_1 = exclude; _a < exclude_1.length; _a++) {
                var excludeTypingName = exclude_1[_a];
                delete inferredTypings[excludeTypingName];
            }
            var newTypingNames = [];
            var cachedTypingPaths = [];
            for (var typing in inferredTypings) {
                if (inferredTypings[typing] !== undefined) {
                    cachedTypingPaths.push(inferredTypings[typing]);
                }
                else {
                    newTypingNames.push(typing);
                }
            }
            return { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch };
            /**
             * Merge a given list of typingNames to the inferredTypings map
             */
            function mergeTypings(typingNames) {
                if (!typingNames) {
                    return;
                }
                for (var _i = 0, typingNames_1 = typingNames; _i < typingNames_1.length; _i++) {
                    var typing = typingNames_1[_i];
                    if (!ts.hasProperty(inferredTypings, typing)) {
                        inferredTypings[typing] = undefined;
                    }
                }
            }
            /**
             * Get the typing info from common package manager json files like package.json or bower.json
             */
            function getTypingNamesFromJson(jsonPath, filesToWatch) {
                var result = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); });
                if (result.config) {
                    var jsonConfig = result.config;
                    filesToWatch.push(jsonPath);
                    if (jsonConfig.dependencies) {
                        mergeTypings(ts.getKeys(jsonConfig.dependencies));
                    }
                    if (jsonConfig.devDependencies) {
                        mergeTypings(ts.getKeys(jsonConfig.devDependencies));
                    }
                    if (jsonConfig.optionalDependencies) {
                        mergeTypings(ts.getKeys(jsonConfig.optionalDependencies));
                    }
                    if (jsonConfig.peerDependencies) {
                        mergeTypings(ts.getKeys(jsonConfig.peerDependencies));
                    }
                }
            }
            /**
             * 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 jsFileNames = ts.filter(fileNames, ts.hasJavaScriptFileExtension);
                var inferredTypingNames = ts.map(jsFileNames, function (f) { return ts.removeFileExtension(ts.getBaseFileName(f.toLowerCase())); });
                var cleanedTypingNames = ts.map(inferredTypingNames, function (f) { return f.replace(/((?:\.|-)min(?=\.|$))|((?:-|\.)\d+)/g, ""); });
                if (safeList === undefined) {
                    mergeTypings(cleanedTypingNames);
                }
                else {
                    mergeTypings(ts.filter(cleanedTypingNames, function (f) { return ts.hasProperty(safeList, f); }));
                }
                var hasJsxFile = ts.forEach(fileNames, function (f) { return ts.scriptKindIs(f, /*LanguageServiceHost*/ undefined, 2 /* JSX */); });
                if (hasJsxFile) {
                    mergeTypings(["react"]);
                }
            }
            /**
             * Infer typing names from node_module folder
             * @param nodeModulesPath is the path to the "node_modules" folder
             */
            function getTypingNamesFromNodeModuleFolder(nodeModulesPath) {
                // Todo: add support for ModuleResolutionHost too
                if (!host.directoryExists(nodeModulesPath)) {
                    return;
                }
                var typingNames = [];
                var fileNames = host.readDirectory(nodeModulesPath, ["*.json"], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
                for (var _i = 0, fileNames_2 = fileNames; _i < fileNames_2.length; _i++) {
                    var fileName = fileNames_2[_i];
                    var normalizedFileName = ts.normalizePath(fileName);
                    if (ts.getBaseFileName(normalizedFileName) !== "package.json") {
                        continue;
                    }
                    var result = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); });
                    if (!result.config) {
                        continue;
                    }
                    var packageJson = result.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 (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;
                    }
                    if (packageJson.typings) {
                        var absolutePath = ts.getNormalizedAbsolutePath(packageJson.typings, ts.getDirectoryPath(normalizedFileName));
                        inferredTypings[packageJson.name] = absolutePath;
                    }
                    else {
                        typingNames.push(packageJson.name);
                    }
                }
                mergeTypings(typingNames);
            }
        }
        JsTyping.discoverTypings = discoverTypings;
    })(JsTyping = ts.JsTyping || (ts.JsTyping = {}));
})(ts || (ts = {}));
/// <reference path="formatting.ts"/>
/// <reference path="..\..\compiler\scanner.ts"/>
/* @internal */
var ts;
(function (ts) {
    var formatting;
    (function (formatting) {
        var standardScanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
        var jsxScanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ false, 1 /* JSX */);
        /**
         * Scanner that is currently used for formatting
         */
        var scanner;
        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 = {}));
        function getFormattingScanner(sourceFile, startPos, endPos) {
            ts.Debug.assert(scanner === undefined);
            scanner = sourceFile.languageVariant === 1 /* JSX */ ? jsxScanner : standardScanner;
            scanner.setText(sourceFile.text);
            scanner.setTextPos(startPos);
            var wasNewLine = true;
            var leadingTrivia;
            var trailingTrivia;
            var savedPos;
            var lastScanAction;
            var lastTokenInfo;
            return {
                advance: advance,
                readTokenInfo: readTokenInfo,
                isOnToken: isOnToken,
                getCurrentLeadingTrivia: function () { return leadingTrivia; },
                lastTrailingTriviaWasNewLine: function () { return wasNewLine; },
                skipToEndOf: skipToEndOf,
                close: function () {
                    ts.Debug.assert(scanner !== undefined);
                    lastTokenInfo = undefined;
                    scanner.setText(undefined);
                    scanner = undefined;
                }
            };
            function advance() {
                ts.Debug.assert(scanner !== undefined);
                lastTokenInfo = undefined;
                var isStarted = scanner.getStartPos() !== startPos;
                if (isStarted) {
                    if (trailingTrivia) {
                        ts.Debug.assert(trailingTrivia.length !== 0);
                        wasNewLine = ts.lastOrUndefined(trailingTrivia).kind === 4 /* NewLineTrivia */;
                    }
                    else {
                        wasNewLine = false;
                    }
                }
                leadingTrivia = undefined;
                trailingTrivia = undefined;
                if (!isStarted) {
                    scanner.scan();
                }
                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();
                    if (!leadingTrivia) {
                        leadingTrivia = [];
                    }
                    leadingTrivia.push(item);
                }
                savedPos = scanner.getStartPos();
            }
            function shouldRescanGreaterThanToken(node) {
                if (node) {
                    switch (node.kind) {
                        case 29 /* GreaterThanEqualsToken */:
                        case 64 /* GreaterThanGreaterThanEqualsToken */:
                        case 65 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                        case 45 /* GreaterThanGreaterThanGreaterThanToken */:
                        case 44 /* GreaterThanGreaterThanToken */:
                            return true;
                    }
                }
                return false;
            }
            function shouldRescanJsxIdentifier(node) {
                if (node.parent) {
                    switch (node.parent.kind) {
                        case 246 /* JsxAttribute */:
                        case 243 /* JsxOpeningElement */:
                        case 245 /* JsxClosingElement */:
                        case 242 /* JsxSelfClosingElement */:
                            return node.kind === 69 /* Identifier */;
                    }
                }
                return false;
            }
            function shouldRescanSlashToken(container) {
                return container.kind === 10 /* RegularExpressionLiteral */;
            }
            function shouldRescanTemplateToken(container) {
                return container.kind === 13 /* TemplateMiddle */ ||
                    container.kind === 14 /* TemplateTail */;
            }
            function startsWithSlashToken(t) {
                return t === 39 /* SlashToken */ || t === 61 /* SlashEqualsToken */;
            }
            function readTokenInfo(n) {
                ts.Debug.assert(scanner !== undefined);
                if (!isOnToken()) {
                    // scanner is not on the token (either advance was not called yet or scanner is already past the end position)
                    return {
                        leadingTrivia: leadingTrivia,
                        trailingTrivia: undefined,
                        token: undefined
                    };
                }
                // 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 */
                                : 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 = scanner.getToken();
                if (expectedScanAction === 1 /* RescanGreaterThanToken */ && currentToken === 27 /* GreaterThanToken */) {
                    currentToken = scanner.reScanGreaterToken();
                    ts.Debug.assert(n.kind === currentToken);
                    lastScanAction = 1 /* RescanGreaterThanToken */;
                }
                else if (expectedScanAction === 2 /* RescanSlashToken */ && startsWithSlashToken(currentToken)) {
                    currentToken = scanner.reScanSlashToken();
                    ts.Debug.assert(n.kind === currentToken);
                    lastScanAction = 2 /* RescanSlashToken */;
                }
                else if (expectedScanAction === 3 /* RescanTemplateToken */ && currentToken === 16 /* CloseBraceToken */) {
                    currentToken = scanner.reScanTemplateToken();
                    lastScanAction = 3 /* RescanTemplateToken */;
                }
                else if (expectedScanAction === 4 /* RescanJsxIdentifier */ && currentToken === 69 /* Identifier */) {
                    currentToken = scanner.scanJsxIdentifier();
                    lastScanAction = 4 /* RescanJsxIdentifier */;
                }
                else {
                    lastScanAction = 0 /* Scan */;
                }
                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 isOnToken() {
                ts.Debug.assert(scanner !== undefined);
                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 = (function () {
            function FormattingContext(sourceFile, formattingRequestKind) {
                this.sourceFile = sourceFile;
                this.formattingRequestKind = formattingRequestKind;
            }
            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, 15 /* OpenBraceToken */, this.sourceFile);
                var closeBrace = ts.findChildOfKind(node, 16 /* 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) {
        (function (FormattingRequestKind) {
            FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument";
            FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection";
            FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter";
            FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon";
            FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 4] = "FormatOnClosingCurlyBrace";
        })(formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {}));
        var 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 = (function () {
            function Rule(Descriptor, Operation, Flag) {
                if (Flag === void 0) { Flag = 0 /* None */; }
                this.Descriptor = Descriptor;
                this.Operation = Operation;
                this.Flag = Flag;
            }
            Rule.prototype.toString = function () {
                return "[desc=" + this.Descriptor + "," +
                    "operation=" + this.Operation + "," +
                    "flag=" + this.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) {
        (function (RuleAction) {
            RuleAction[RuleAction["Ignore"] = 1] = "Ignore";
            RuleAction[RuleAction["Space"] = 2] = "Space";
            RuleAction[RuleAction["NewLine"] = 4] = "NewLine";
            RuleAction[RuleAction["Delete"] = 8] = "Delete";
        })(formatting.RuleAction || (formatting.RuleAction = {}));
        var 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 = (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) {
        (function (RuleFlags) {
            RuleFlags[RuleFlags["None"] = 0] = "None";
            RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines";
        })(formatting.RuleFlags || (formatting.RuleFlags = {}));
        var 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 = (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 = (function () {
            function RuleOperationContext() {
                var funcs = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    funcs[_i - 0] = 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 = (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, 23 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeColon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 54 /* 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, 53 /* QuestionToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                this.SpaceAfterColon = new formatting.Rule(formatting.RuleDescriptor.create3(54 /* 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(53 /* 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(53 /* QuestionToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterSemicolon = new formatting.Rule(formatting.RuleDescriptor.create3(23 /* 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(16 /* CloseBraceToken */, formatting.Shared.TokenRange.Any), 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(16 /* CloseBraceToken */, 80 /* ElseKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBetweenCloseBraceAndWhile = new formatting.Rule(formatting.RuleDescriptor.create1(16 /* CloseBraceToken */, 104 /* WhileKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(16 /* CloseBraceToken */, formatting.Shared.TokenRange.FromTokens([18 /* CloseParenToken */, 20 /* CloseBracketToken */, 24 /* CommaToken */, 23 /* 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, 21 /* DotToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterDot = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* 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.Any, 19 /* OpenBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(20 /* 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, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 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([69 /* Identifier */, 3 /* MultiLineCommentTrivia */, 73 /* ClassKeyword */, 82 /* ExportKeyword */, 89 /* ImportKeyword */]);
                this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                // Place a space before open brace in a control flow construct
                this.ControlOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([18 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 79 /* DoKeyword */, 100 /* TryKeyword */, 85 /* FinallyKeyword */, 80 /* ElseKeyword */]);
                this.SpaceBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 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(15 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSingleLineBlockContext), 2 /* Space */));
                this.SpaceBeforeCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 16 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSingleLineBlockContext), 2 /* Space */));
                this.NoSpaceBetweenEmptyBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(15 /* OpenBraceToken */, 16 /* 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(15 /* 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, 16 /* 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(41 /* PlusPlusToken */, formatting.Shared.TokenRange.UnaryPreincrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterUnaryPredecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(42 /* 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, 41 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeUnaryPostdecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostdecrementExpressions, 42 /* 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(41 /* PlusPlusToken */, 35 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterAddWhenFollowedByUnaryPlus = new formatting.Rule(formatting.RuleDescriptor.create1(35 /* PlusToken */, 35 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterAddWhenFollowedByPreincrement = new formatting.Rule(formatting.RuleDescriptor.create1(35 /* PlusToken */, 41 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterPostdecrementWhenFollowedBySubtract = new formatting.Rule(formatting.RuleDescriptor.create1(42 /* MinusMinusToken */, 36 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterSubtractWhenFollowedByUnaryMinus = new formatting.Rule(formatting.RuleDescriptor.create1(36 /* MinusToken */, 36 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                this.SpaceAfterSubtractWhenFollowedByPredecrement = new formatting.Rule(formatting.RuleDescriptor.create1(36 /* MinusToken */, 42 /* 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, 24 /* CommaToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterCertainKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([102 /* VarKeyword */, 98 /* ThrowKeyword */, 92 /* NewKeyword */, 78 /* DeleteKeyword */, 94 /* ReturnKeyword */, 101 /* TypeOfKeyword */, 119 /* AwaitKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceAfterLetConstInVariableDeclaration = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([108 /* LetKeyword */, 74 /* 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, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), 8 /* Delete */));
                this.SpaceAfterFunctionInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create3(87 /* FunctionKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                this.NoSpaceBeforeOpenParenInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), 8 /* Delete */));
                this.SpaceAfterVoidOperator = new formatting.Rule(formatting.RuleDescriptor.create3(103 /* 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(94 /* ReturnKeyword */, 23 /* 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([18 /* CloseParenToken */, 79 /* DoKeyword */, 80 /* ElseKeyword */, 71 /* 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([100 /* TryKeyword */, 85 /* FinallyKeyword */]), 15 /* 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([123 /* GetKeyword */, 131 /* SetKeyword */]), 69 /* 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
                // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
                this.NoSpaceAfterConstructor = new formatting.Rule(formatting.RuleDescriptor.create1(121 /* ConstructorKeyword */, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(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([125 /* ModuleKeyword */, 129 /* RequireKeyword */]), 17 /* 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([115 /* AbstractKeyword */, 73 /* ClassKeyword */, 122 /* DeclareKeyword */, 77 /* DefaultKeyword */, 81 /* EnumKeyword */, 82 /* ExportKeyword */, 83 /* ExtendsKeyword */, 123 /* GetKeyword */, 106 /* ImplementsKeyword */, 89 /* ImportKeyword */, 107 /* InterfaceKeyword */, 125 /* ModuleKeyword */, 126 /* NamespaceKeyword */, 110 /* PrivateKeyword */, 112 /* PublicKeyword */, 111 /* ProtectedKeyword */, 131 /* SetKeyword */, 113 /* StaticKeyword */, 134 /* TypeKeyword */, 136 /* FromKeyword */]), 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([83 /* ExtendsKeyword */, 106 /* ImplementsKeyword */, 136 /* 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 */, 15 /* 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, 34 /* EqualsGreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceAfterArrow = new formatting.Rule(formatting.RuleDescriptor.create3(34 /* 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(22 /* DotDotDotToken */, 69 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterOptionalParameters = new formatting.Rule(formatting.RuleDescriptor.create3(53 /* QuestionToken */, formatting.Shared.TokenRange.FromTokens([18 /* CloseParenToken */, 24 /* 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, 25 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceBetweenCloseParenAndAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create1(18 /* CloseParenToken */, 25 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceAfterOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(25 /* 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, 27 /* GreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceAfterCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(27 /* GreaterThanToken */, formatting.Shared.TokenRange.FromTokens([17 /* OpenParenToken */, 19 /* OpenBracketToken */, 27 /* GreaterThanToken */, 24 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), 8 /* Delete */));
                this.NoSpaceAfterTypeAssertion = new formatting.Rule(formatting.RuleDescriptor.create3(27 /* GreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsTypeAssertionContext), 8 /* Delete */));
                // Remove spaces in empty interface literals. e.g.: x: {}
                this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(15 /* OpenBraceToken */, 16 /* 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, 55 /* AtToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceAfterAt = new formatting.Rule(formatting.RuleDescriptor.create3(55 /* 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([115 /* AbstractKeyword */, 69 /* Identifier */, 82 /* ExportKeyword */, 77 /* DefaultKeyword */, 73 /* ClassKeyword */, 113 /* StaticKeyword */, 112 /* PublicKeyword */, 110 /* PrivateKeyword */, 111 /* ProtectedKeyword */, 123 /* GetKeyword */, 131 /* SetKeyword */, 19 /* OpenBracketToken */, 37 /* AsteriskToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), 2 /* Space */));
                this.NoSpaceBetweenFunctionKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(87 /* FunctionKeyword */, 37 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 8 /* Delete */));
                this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(37 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([69 /* Identifier */, 17 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */));
                this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(114 /* YieldKeyword */, 37 /* 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([114 /* YieldKeyword */, 37 /* 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(118 /* AsyncKeyword */, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsArrowFunctionContext, Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBetweenAsyncAndFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(118 /* AsyncKeyword */, 87 /* FunctionKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // template string
                this.NoSpaceBetweenTagAndTemplateString = new formatting.Rule(formatting.RuleDescriptor.create3(69 /* Identifier */, formatting.Shared.TokenRange.FromTokens([11 /* NoSubstitutionTemplateLiteral */, 12 /* TemplateHead */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // 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.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, 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,
                    // TypeScript-specific rules
                    this.NoSpaceAfterConstructor, 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.NoSpaceAfterTypeAssertion,
                    this.SpaceBeforeAt,
                    this.NoSpaceAfterAt,
                    this.SpaceAfterDecorator,
                ];
                // 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.NoSpaceBeforeOpenParenInFuncDecl,
                    this.SpaceBetweenStatements, this.SpaceAfterTryFinally
                ];
                ///
                /// Rules controlled by user options
                ///
                // Insert space after comma delimiter
                this.SpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(24 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), 2 /* Space */));
                this.NoSpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(24 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(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.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.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.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.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, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 2 /* Space */));
                this.NoSpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(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, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(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, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                // Open Brace braces after control block
                this.NewLineBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 15 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                // Insert space after semicolon in for statement
                this.SpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(23 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 2 /* Space */));
                this.NoSpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(23 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsForContext), 8 /* Delete */));
                // Insert space after opening and before closing nonempty parenthesis
                this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(17 /* OpenParenToken */, 18 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                // Insert space after opening and before closing nonempty brackets
                this.SpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.SpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBetweenBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(19 /* OpenBracketToken */, 20 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 20 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(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([12 /* TemplateHead */, 13 /* TemplateMiddle */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceAfterTemplateHeadAndMiddle = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([12 /* TemplateHead */, 13 /* TemplateMiddle */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                this.NoSpaceBeforeTemplateMiddleAndTail = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([13 /* TemplateMiddle */, 14 /* TemplateTail */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 8 /* Delete */));
                this.SpaceBeforeTemplateMiddleAndTail = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([13 /* TemplateMiddle */, 14 /* TemplateTail */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), 2 /* Space */));
                // No space after { and before } in JSX expression
                this.NoSpaceAfterOpenBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create3(15 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), 8 /* Delete */));
                this.SpaceAfterOpenBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create3(15 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), 2 /* Space */));
                this.NoSpaceBeforeCloseBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 16 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), 8 /* Delete */));
                this.SpaceBeforeCloseBraceInJsxExpression = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 16 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), 2 /* Space */));
                // Insert space after function keyword for anonymous functions
                this.SpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(87 /* FunctionKeyword */, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                this.NoSpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(87 /* FunctionKeyword */, 17 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 8 /* Delete */));
            }
            Rules.prototype.getRuleName = function (rule) {
                var o = this;
                for (var name_40 in o) {
                    if (o[name_40] === rule) {
                        return name_40;
                    }
                }
                throw new Error("Unknown rule");
            };
            ///
            /// Contexts
            ///
            Rules.IsForContext = function (context) {
                return context.contextNode.kind === 206 /* ForStatement */;
            };
            Rules.IsNotForContext = function (context) {
                return !Rules.IsForContext(context);
            };
            Rules.IsBinaryOpContext = function (context) {
                switch (context.contextNode.kind) {
                    case 187 /* BinaryExpression */:
                    case 188 /* ConditionalExpression */:
                    case 195 /* AsExpression */:
                    case 238 /* ExportSpecifier */:
                    case 234 /* ImportSpecifier */:
                    case 154 /* TypePredicate */:
                    case 162 /* UnionType */:
                    case 163 /* IntersectionType */:
                        return true;
                    // equals in binding elements: function foo([[x, y] = [1, 2]])
                    case 169 /* BindingElement */:
                    // equals in type X = ...
                    case 223 /* TypeAliasDeclaration */:
                    // equal in import a = module('a');
                    case 229 /* ImportEqualsDeclaration */:
                    // equal in let a = 0;
                    case 218 /* VariableDeclaration */:
                    // equal in p = 0;
                    case 142 /* Parameter */:
                    case 255 /* EnumMember */:
                    case 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                        return context.currentTokenSpan.kind === 56 /* EqualsToken */ || context.nextTokenSpan.kind === 56 /* EqualsToken */;
                    // "in" keyword in for (let x in []) { }
                    case 207 /* ForInStatement */:
                        return context.currentTokenSpan.kind === 90 /* InKeyword */ || context.nextTokenSpan.kind === 90 /* InKeyword */;
                    // Technically, "of" is not a binary operator, but format it the same way as "in"
                    case 208 /* ForOfStatement */:
                        return context.currentTokenSpan.kind === 138 /* OfKeyword */ || context.nextTokenSpan.kind === 138 /* OfKeyword */;
                }
                return false;
            };
            Rules.IsNotBinaryOpContext = function (context) {
                return !Rules.IsBinaryOpContext(context);
            };
            Rules.IsConditionalOperatorContext = function (context) {
                return context.contextNode.kind === 188 /* ConditionalExpression */;
            };
            Rules.IsSameLineTokenOrBeforeMultilineBlockContext = function (context) {
                //// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction.
                ////
                //// Ex:
                //// if (1)     { ....
                ////      * ) and { are on the same line so apply the rule. Here we don't care whether it's same or multi block context
                ////
                //// Ex:
                //// if (1)
                //// { ... }
                ////      * ) and { are on different lines. We only need to format if the block is multiline context. So in this case we don't format.
                ////
                //// Ex:
                //// if (1)
                //// { ...
                //// }
                ////      * ) and { are on different lines. We only need to format if the block is multiline context. So in this case we format.
                return context.TokensAreOnSameLine() || Rules.IsBeforeMultilineBlockContext(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 199 /* Block */:
                    case 227 /* CaseBlock */:
                    case 171 /* ObjectLiteralExpression */:
                    case 226 /* ModuleBlock */:
                        return true;
                }
                return false;
            };
            Rules.IsFunctionDeclContext = function (context) {
                switch (context.contextNode.kind) {
                    case 220 /* FunctionDeclaration */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    // case SyntaxKind.MemberFunctionDeclaration:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    // case SyntaxKind.MethodSignature:
                    case 151 /* CallSignature */:
                    case 179 /* FunctionExpression */:
                    case 148 /* Constructor */:
                    case 180 /* ArrowFunction */:
                    // case SyntaxKind.ConstructorDeclaration:
                    // case SyntaxKind.SimpleArrowFunctionExpression:
                    // case SyntaxKind.ParenthesizedArrowFunctionExpression:
                    case 222 /* InterfaceDeclaration */:
                        return true;
                }
                return false;
            };
            Rules.IsFunctionDeclarationOrFunctionExpressionContext = function (context) {
                return context.contextNode.kind === 220 /* FunctionDeclaration */ || context.contextNode.kind === 179 /* FunctionExpression */;
            };
            Rules.IsTypeScriptDeclWithBlockContext = function (context) {
                return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode);
            };
            Rules.NodeIsTypeScriptDeclWithBlockContext = function (node) {
                switch (node.kind) {
                    case 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 222 /* InterfaceDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 159 /* TypeLiteral */:
                    case 225 /* ModuleDeclaration */:
                    case 236 /* ExportDeclaration */:
                    case 237 /* NamedExports */:
                    case 230 /* ImportDeclaration */:
                    case 233 /* NamedImports */:
                        return true;
                }
                return false;
            };
            Rules.IsAfterCodeBlockContext = function (context) {
                switch (context.currentTokenParent.kind) {
                    case 221 /* ClassDeclaration */:
                    case 225 /* ModuleDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 199 /* Block */:
                    case 252 /* CatchClause */:
                    case 226 /* ModuleBlock */:
                    case 213 /* SwitchStatement */:
                        return true;
                }
                return false;
            };
            Rules.IsControlDeclContext = function (context) {
                switch (context.contextNode.kind) {
                    case 203 /* IfStatement */:
                    case 213 /* SwitchStatement */:
                    case 206 /* ForStatement */:
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                    case 205 /* WhileStatement */:
                    case 216 /* TryStatement */:
                    case 204 /* DoStatement */:
                    case 212 /* WithStatement */:
                    // TODO
                    // case SyntaxKind.ElseClause:
                    case 252 /* CatchClause */:
                        return true;
                    default:
                        return false;
                }
            };
            Rules.IsObjectContext = function (context) {
                return context.contextNode.kind === 171 /* ObjectLiteralExpression */;
            };
            Rules.IsFunctionCallContext = function (context) {
                return context.contextNode.kind === 174 /* CallExpression */;
            };
            Rules.IsNewContext = function (context) {
                return context.contextNode.kind === 175 /* NewExpression */;
            };
            Rules.IsFunctionCallOrNewContext = function (context) {
                return Rules.IsFunctionCallContext(context) || Rules.IsNewContext(context);
            };
            Rules.IsPreviousTokenNotComma = function (context) {
                return context.currentTokenSpan.kind !== 24 /* CommaToken */;
            };
            Rules.IsNextTokenNotCloseBracket = function (context) {
                return context.nextTokenSpan.kind !== 20 /* CloseBracketToken */;
            };
            Rules.IsArrowFunctionContext = function (context) {
                return context.contextNode.kind === 180 /* ArrowFunction */;
            };
            Rules.IsNonJsxSameLineTokenContext = function (context) {
                return context.TokensAreOnSameLine() && context.contextNode.kind !== 244 /* JsxText */;
            };
            Rules.isNonJsxElementContext = function (context) {
                return context.contextNode.kind !== 241 /* JsxElement */;
            };
            Rules.isJsxExpressionContext = function (context) {
                return context.contextNode.kind === 248 /* JsxExpression */;
            };
            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.isExpression(node)) {
                    node = node.parent;
                }
                return node.kind === 143 /* Decorator */;
            };
            Rules.IsStartOfVariableDeclarationList = function (context) {
                return context.currentTokenParent.kind === 219 /* 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 === 225 /* ModuleDeclaration */;
            };
            Rules.IsObjectTypeContext = function (context) {
                return context.contextNode.kind === 159 /* TypeLiteral */; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
            };
            Rules.IsTypeArgumentOrParameterOrAssertion = function (token, parent) {
                if (token.kind !== 25 /* LessThanToken */ && token.kind !== 27 /* GreaterThanToken */) {
                    return false;
                }
                switch (parent.kind) {
                    case 155 /* TypeReference */:
                    case 177 /* TypeAssertionExpression */:
                    case 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 222 /* InterfaceDeclaration */:
                    case 220 /* FunctionDeclaration */:
                    case 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 151 /* CallSignature */:
                    case 152 /* ConstructSignature */:
                    case 174 /* CallExpression */:
                    case 175 /* NewExpression */:
                    case 194 /* 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 === 177 /* TypeAssertionExpression */;
            };
            Rules.IsVoidOpContext = function (context) {
                return context.currentTokenSpan.kind === 103 /* VoidKeyword */ && context.currentTokenParent.kind === 183 /* VoidExpression */;
            };
            Rules.IsYieldOrYieldStarWithOperand = function (context) {
                return context.contextNode.kind === 190 /* YieldExpression */ && context.contextNode.expression !== undefined;
            };
            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 = (function () {
            function RulesMap() {
                this.map = [];
                this.mapRowLength = 0;
            }
            RulesMap.create = function (rules) {
                var result = new RulesMap();
                result.Initialize(rules);
                return result;
            };
            RulesMap.prototype.Initialize = function (rules) {
                this.mapRowLength = 138 /* LastToken */ + 1;
                this.map = new Array(this.mapRowLength * this.mapRowLength); // new Array<RulesBucket>(this.mapRowLength * this.mapRowLength);
                // This array is used only during construction of the rulesbucket in the map
                var rulesBucketConstructionStateList = new Array(this.map.length); // new Array<RulesBucketConstructionState>(this.map.length);
                this.FillRules(rules, rulesBucketConstructionStateList);
                return this.map;
            };
            RulesMap.prototype.FillRules = function (rules, rulesBucketConstructionStateList) {
                var _this = this;
                rules.forEach(function (rule) {
                    _this.FillRule(rule, rulesBucketConstructionStateList);
                });
            };
            RulesMap.prototype.GetRuleBucketIndex = function (row, column) {
                var rulesBucketIndex = (row * this.mapRowLength) + column;
                // Debug.Assert(rulesBucketIndex < this.map.Length, "Trying to access an index outside the array.");
                return rulesBucketIndex;
            };
            RulesMap.prototype.FillRule = function (rule, rulesBucketConstructionStateList) {
                var _this = this;
                var specificRule = rule.Descriptor.LeftTokenRange !== formatting.Shared.TokenRange.Any &&
                    rule.Descriptor.RightTokenRange !== formatting.Shared.TokenRange.Any;
                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;
        (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";
        })(formatting.RulesPosition || (formatting.RulesPosition = {}));
        var RulesPosition = formatting.RulesPosition;
        var RulesBucketConstructionState = (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 = (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 TokenRangeAccess = (function () {
                function TokenRangeAccess(from, to, except) {
                    this.tokens = [];
                    for (var token = from; token <= to; token++) {
                        if (ts.indexOf(except, token) < 0) {
                            this.tokens.push(token);
                        }
                    }
                }
                TokenRangeAccess.prototype.GetTokens = function () {
                    return this.tokens;
                };
                TokenRangeAccess.prototype.Contains = function (token) {
                    return this.tokens.indexOf(token) >= 0;
                };
                return TokenRangeAccess;
            }());
            Shared.TokenRangeAccess = TokenRangeAccess;
            var TokenValuesAccess = (function () {
                function TokenValuesAccess(tks) {
                    this.tokens = tks && tks.length ? tks : [];
                }
                TokenValuesAccess.prototype.GetTokens = function () {
                    return this.tokens;
                };
                TokenValuesAccess.prototype.Contains = function (token) {
                    return this.tokens.indexOf(token) >= 0;
                };
                return TokenValuesAccess;
            }());
            Shared.TokenValuesAccess = TokenValuesAccess;
            var TokenSingleValueAccess = (function () {
                function TokenSingleValueAccess(token) {
                    this.token = token;
                }
                TokenSingleValueAccess.prototype.GetTokens = function () {
                    return [this.token];
                };
                TokenSingleValueAccess.prototype.Contains = function (tokenValue) {
                    return tokenValue === this.token;
                };
                return TokenSingleValueAccess;
            }());
            Shared.TokenSingleValueAccess = TokenSingleValueAccess;
            var TokenAllAccess = (function () {
                function TokenAllAccess() {
                }
                TokenAllAccess.prototype.GetTokens = function () {
                    var result = [];
                    for (var token = 0 /* FirstToken */; token <= 138 /* LastToken */; token++) {
                        result.push(token);
                    }
                    return result;
                };
                TokenAllAccess.prototype.Contains = function (tokenValue) {
                    return true;
                };
                TokenAllAccess.prototype.toString = function () {
                    return "[allTokens]";
                };
                return TokenAllAccess;
            }());
            Shared.TokenAllAccess = TokenAllAccess;
            var TokenRange = (function () {
                function TokenRange(tokenAccess) {
                    this.tokenAccess = tokenAccess;
                }
                TokenRange.FromToken = function (token) {
                    return new TokenRange(new TokenSingleValueAccess(token));
                };
                TokenRange.FromTokens = function (tokens) {
                    return new TokenRange(new TokenValuesAccess(tokens));
                };
                TokenRange.FromRange = function (f, to, except) {
                    if (except === void 0) { except = []; }
                    return new TokenRange(new TokenRangeAccess(f, to, except));
                };
                TokenRange.AllTokens = function () {
                    return new TokenRange(new TokenAllAccess());
                };
                TokenRange.prototype.GetTokens = function () {
                    return this.tokenAccess.GetTokens();
                };
                TokenRange.prototype.Contains = function (token) {
                    return this.tokenAccess.Contains(token);
                };
                TokenRange.prototype.toString = function () {
                    return this.tokenAccess.toString();
                };
                TokenRange.Any = TokenRange.AllTokens();
                TokenRange.AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([3 /* MultiLineCommentTrivia */]));
                TokenRange.Keywords = TokenRange.FromRange(70 /* FirstKeyword */, 138 /* LastKeyword */);
                TokenRange.BinaryOperators = TokenRange.FromRange(25 /* FirstBinaryOperator */, 68 /* LastBinaryOperator */);
                TokenRange.BinaryKeywordOperators = TokenRange.FromTokens([90 /* InKeyword */, 91 /* InstanceOfKeyword */, 138 /* OfKeyword */, 116 /* AsKeyword */, 124 /* IsKeyword */]);
                TokenRange.UnaryPrefixOperators = TokenRange.FromTokens([41 /* PlusPlusToken */, 42 /* MinusMinusToken */, 50 /* TildeToken */, 49 /* ExclamationToken */]);
                TokenRange.UnaryPrefixExpressions = TokenRange.FromTokens([8 /* NumericLiteral */, 69 /* Identifier */, 17 /* OpenParenToken */, 19 /* OpenBracketToken */, 15 /* OpenBraceToken */, 97 /* ThisKeyword */, 92 /* NewKeyword */]);
                TokenRange.UnaryPreincrementExpressions = TokenRange.FromTokens([69 /* Identifier */, 17 /* OpenParenToken */, 97 /* ThisKeyword */, 92 /* NewKeyword */]);
                TokenRange.UnaryPostincrementExpressions = TokenRange.FromTokens([69 /* Identifier */, 18 /* CloseParenToken */, 20 /* CloseBracketToken */, 92 /* NewKeyword */]);
                TokenRange.UnaryPredecrementExpressions = TokenRange.FromTokens([69 /* Identifier */, 17 /* OpenParenToken */, 97 /* ThisKeyword */, 92 /* NewKeyword */]);
                TokenRange.UnaryPostdecrementExpressions = TokenRange.FromTokens([69 /* Identifier */, 18 /* CloseParenToken */, 20 /* CloseBracketToken */, 92 /* NewKeyword */]);
                TokenRange.Comments = TokenRange.FromTokens([2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */]);
                TokenRange.TypeNames = TokenRange.FromTokens([69 /* Identifier */, 130 /* NumberKeyword */, 132 /* StringKeyword */, 120 /* BooleanKeyword */, 133 /* SymbolKeyword */, 103 /* VoidKeyword */, 117 /* AnyKeyword */]);
                return TokenRange;
            }());
            Shared.TokenRange = 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 = (function () {
            function RulesProvider() {
                this.globalRules = new formatting.Rules();
            }
            RulesProvider.prototype.getRuleName = function (rule) {
                return this.globalRules.getRuleName(rule);
            };
            RulesProvider.prototype.getRuleByName = function (name) {
                return this.globalRules[name];
            };
            RulesProvider.prototype.getRulesMap = function () {
                return this.rulesMap;
            };
            RulesProvider.prototype.ensureUpToDate = function (options) {
                if (!this.options || !ts.compareDataObjects(this.options, options)) {
                    var activeRules = this.createActiveRules(options);
                    var rulesMap = formatting.RulesMap.create(activeRules);
                    this.activeRules = activeRules;
                    this.rulesMap = rulesMap;
                    this.options = ts.clone(options);
                }
            };
            RulesProvider.prototype.createActiveRules = function (options) {
                var rules = this.globalRules.HighPriorityCommonRules.slice(0);
                if (options.InsertSpaceAfterCommaDelimiter) {
                    rules.push(this.globalRules.SpaceAfterComma);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterComma);
                }
                if (options.InsertSpaceAfterFunctionKeywordForAnonymousFunctions) {
                    rules.push(this.globalRules.SpaceAfterAnonymousFunctionKeyword);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterAnonymousFunctionKeyword);
                }
                if (options.InsertSpaceAfterKeywordsInControlFlowStatements) {
                    rules.push(this.globalRules.SpaceAfterKeywordInControl);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterKeywordInControl);
                }
                if (options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis) {
                    rules.push(this.globalRules.SpaceAfterOpenParen);
                    rules.push(this.globalRules.SpaceBeforeCloseParen);
                    rules.push(this.globalRules.NoSpaceBetweenParens);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterOpenParen);
                    rules.push(this.globalRules.NoSpaceBeforeCloseParen);
                    rules.push(this.globalRules.NoSpaceBetweenParens);
                }
                if (options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets) {
                    rules.push(this.globalRules.SpaceAfterOpenBracket);
                    rules.push(this.globalRules.SpaceBeforeCloseBracket);
                    rules.push(this.globalRules.NoSpaceBetweenBrackets);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterOpenBracket);
                    rules.push(this.globalRules.NoSpaceBeforeCloseBracket);
                    rules.push(this.globalRules.NoSpaceBetweenBrackets);
                }
                if (options.InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces) {
                    rules.push(this.globalRules.SpaceAfterTemplateHeadAndMiddle);
                    rules.push(this.globalRules.SpaceBeforeTemplateMiddleAndTail);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterTemplateHeadAndMiddle);
                    rules.push(this.globalRules.NoSpaceBeforeTemplateMiddleAndTail);
                }
                if (options.InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces) {
                    rules.push(this.globalRules.SpaceAfterOpenBraceInJsxExpression);
                    rules.push(this.globalRules.SpaceBeforeCloseBraceInJsxExpression);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterOpenBraceInJsxExpression);
                    rules.push(this.globalRules.NoSpaceBeforeCloseBraceInJsxExpression);
                }
                if (options.InsertSpaceAfterSemicolonInForStatements) {
                    rules.push(this.globalRules.SpaceAfterSemicolonInFor);
                }
                else {
                    rules.push(this.globalRules.NoSpaceAfterSemicolonInFor);
                }
                if (options.InsertSpaceBeforeAndAfterBinaryOperators) {
                    rules.push(this.globalRules.SpaceBeforeBinaryOperator);
                    rules.push(this.globalRules.SpaceAfterBinaryOperator);
                }
                else {
                    rules.push(this.globalRules.NoSpaceBeforeBinaryOperator);
                    rules.push(this.globalRules.NoSpaceAfterBinaryOperator);
                }
                if (options.PlaceOpenBraceOnNewLineForControlBlocks) {
                    rules.push(this.globalRules.NewLineBeforeOpenBraceInControl);
                }
                if (options.PlaceOpenBraceOnNewLineForFunctions) {
                    rules.push(this.globalRules.NewLineBeforeOpenBraceInFunction);
                    rules.push(this.globalRules.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock);
                }
                rules = rules.concat(this.globalRules.LowPriorityCommonRules);
                return rules;
            };
            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) {
            return formatOutermostParent(position, 23 /* SemicolonToken */, sourceFile, options, rulesProvider, 3 /* FormatOnSemicolon */);
        }
        formatting.formatOnSemicolon = formatOnSemicolon;
        function formatOnClosingCurly(position, sourceFile, rulesProvider, options) {
            return formatOutermostParent(position, 16 /* CloseBraceToken */, sourceFile, options, rulesProvider, 4 /* 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;
        function formatOutermostParent(position, expectedLastToken, sourceFile, options, rulesProvider, requestKind) {
            var parent = findOutermostParent(position, expectedLastToken, sourceFile);
            if (!parent) {
                return [];
            }
            var span = {
                pos: ts.getLineStartPositionForPosition(parent.getStart(sourceFile), sourceFile),
                end: parent.end
            };
            return formatSpan(span, sourceFile, options, rulesProvider, requestKind);
        }
        function findOutermostParent(position, expectedTokenKind, sourceFile) {
            var precedingToken = ts.findPrecedingToken(position, sourceFile);
            // when it is claimed that trigger character was typed at given position
            // we verify that there is a token with a matching kind whose end is equal to position (because the character was just typed).
            // If this condition is not hold - then trigger character was typed in some other context,
            // i.e.in comment and thus should not trigger autoformatting
            if (!precedingToken ||
                precedingToken.kind !== expectedTokenKind ||
                position !== precedingToken.getEnd()) {
                return undefined;
            }
            // walk up and search for the parent node that ends at the same position with precedingToken.
            // for cases like this
            //
            // let x = 1;
            // while (true) {
            // }
            // after typing close curly in while statement we want to reformat just the while statement.
            // However if we just walk upwards searching for the parent that has the same end value -
            // we'll end up with the whole source file. isListElement allows to stop on the list element level
            var current = precedingToken;
            while (current &&
                current.parent &&
                current.parent.end === precedingToken.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 221 /* ClassDeclaration */:
                case 222 /* InterfaceDeclaration */:
                    return ts.rangeContainsRange(parent.members, node);
                case 225 /* ModuleDeclaration */:
                    var body = parent.body;
                    return body && body.kind === 199 /* Block */ && ts.rangeContainsRange(body.statements, node);
                case 256 /* SourceFile */:
                case 199 /* Block */:
                case 226 /* ModuleBlock */:
                    return ts.rangeContainsRange(parent.statements, node);
                case 252 /* 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(r) {
                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;
        }
        function formatSpan(originalRange, sourceFile, options, rulesProvider, requestKind) {
            var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange);
            // formatting context is used by rules provider
            var formattingContext = new formatting.FormattingContext(sourceFile, requestKind);
            // find the smallest node that fully wraps the range and compute the initial indentation for the node
            var enclosingNode = findEnclosingNode(originalRange, sourceFile);
            var formattingScanner = formatting.getFormattingScanner(sourceFile, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end);
            var initialIndentation = formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options);
            var previousRangeHasError;
            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;
                }
                var delta = getOwnOrInheritedDelta(enclosingNode, options, sourceFile);
                processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta);
            }
            if (!formattingScanner.isOnToken()) {
                var leadingTrivia = formattingScanner.getCurrentLeadingTrivia();
                if (leadingTrivia) {
                    processTrivia(leadingTrivia, enclosingNode, enclosingNode, undefined);
                    trimTrailingWhitespacesForRemainingRange();
                }
            }
            formattingScanner.close();
            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 221 /* ClassDeclaration */: return 73 /* ClassKeyword */;
                    case 222 /* InterfaceDeclaration */: return 107 /* InterfaceKeyword */;
                    case 220 /* FunctionDeclaration */: return 87 /* FunctionKeyword */;
                    case 224 /* EnumDeclaration */: return 224 /* EnumDeclaration */;
                    case 149 /* GetAccessor */: return 123 /* GetKeyword */;
                    case 150 /* SetAccessor */: return 131 /* SetKeyword */;
                    case 147 /* MethodDeclaration */:
                        if (node.asteriskToken) {
                            return 37 /* AsteriskToken */;
                        }
                    // fall-through
                    case 145 /* PropertyDeclaration */:
                    case 142 /* Parameter */:
                        return node.name.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 16 /* CloseBraceToken */:
                            case 20 /* CloseBracketToken */:
                            case 18 /* 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 15 /* OpenBraceToken */:
                            case 16 /* CloseBraceToken */:
                            case 19 /* OpenBracketToken */:
                            case 20 /* CloseBracketToken */:
                            case 17 /* OpenParenToken */:
                            case 18 /* CloseParenToken */:
                            case 80 /* ElseKeyword */:
                            case 104 /* WhileKeyword */:
                            case 55 /* AtToken */:
                                return indentation;
                            default:
                                // 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, 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);
                }
                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
                    var childIndentationAmount = -1 /* Unknown */;
                    if (isListItem) {
                        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);
                    }
                    if (!formattingScanner.isOnToken()) {
                        return inheritedIndentation;
                    }
                    if (ts.isToken(child)) {
                        // 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);
                        consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child);
                        return inheritedIndentation;
                    }
                    var effectiveParentStartLine = child.kind === 143 /* 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 === 170 /* ArrayLiteralExpression */ && inheritedIndentation === -1 /* Unknown */) {
                        inheritedIndentation = childIndentation.indentation;
                    }
                    return inheritedIndentation;
                }
                function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) {
                    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);
                            }
                            else {
                                // consume any tokens that precede the list as child elements of 'node' using its indentation scope
                                consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation);
                            }
                        }
                    }
                    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);
                            }
                        }
                    }
                }
                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 && !previousRangeHasError) {
                    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;
                previousRangeHasError = rangeHasError;
                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 !== tokenStart.character || indentationIsDifferent(indentationString, startLinePosition)) {
                        recordReplace(startLinePosition, tokenStart.character, indentationString);
                    }
                }
            }
            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, len = parts.length; i < len; 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 only 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;
                }
            }
        }
        function getOpenTokenForList(node, list) {
            switch (node.kind) {
                case 148 /* Constructor */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 180 /* ArrowFunction */:
                    if (node.typeParameters === list) {
                        return 25 /* LessThanToken */;
                    }
                    else if (node.parameters === list) {
                        return 17 /* OpenParenToken */;
                    }
                    break;
                case 174 /* CallExpression */:
                case 175 /* NewExpression */:
                    if (node.typeArguments === list) {
                        return 25 /* LessThanToken */;
                    }
                    else if (node.arguments === list) {
                        return 17 /* OpenParenToken */;
                    }
                    break;
                case 155 /* TypeReference */:
                    if (node.typeArguments === list) {
                        return 25 /* LessThanToken */;
                    }
            }
            return 0 /* Unknown */;
        }
        function getCloseTokenForOpenToken(kind) {
            switch (kind) {
                case 17 /* OpenParenToken */:
                    return 18 /* CloseParenToken */;
                case 25 /* LessThanToken */:
                    return 27 /* 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 = {}));
            function getIndentation(position, sourceFile, options) {
                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);
                if (!precedingToken) {
                    return getBaseIndentation(options);
                }
                // no indentation in string \regex\template literals
                var precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
                if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) {
                    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.isWhiteSpace(char)) {
                            break;
                        }
                        current_1--;
                    }
                    var lineStart = ts.getLineStartPositionForPosition(current_1, sourceFile);
                    return SmartIndenter.findFirstNonWhitespaceColumn(lineStart, current_1, sourceFile, options);
                }
                if (precedingToken.kind === 24 /* CommaToken */ && precedingToken.parent.kind !== 187 /* 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);
                        if (nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile)) {
                            indentationDelta = 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 getBaseIndentation(options) {
                return options.BaseIndentSize || 0;
            }
            SmartIndenter.getBaseIndentation = getBaseIndentation;
            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 getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, options) {
                var parent = current.parent;
                var parentStart;
                // walk upwards and collect indentations for pairs of parent-child nodes
                // indentation is not added if parent and child nodes start on the same line or if parent is IfStatement and child starts on the same line with '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;
                        }
                    }
                    parentStart = getParentStart(parent, current, sourceFile);
                    var parentAndChildShareLine = parentStart.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;
                    }
                    current = parent;
                    currentStart = parentStart;
                    parent = current.parent;
                }
                return indentationDelta + getBaseIndentation(options);
            }
            function getParentStart(parent, child, sourceFile) {
                var containingList = getContainingList(child, sourceFile);
                if (containingList) {
                    return sourceFile.getLineAndCharacterOfPosition(containingList.pos);
                }
                return sourceFile.getLineAndCharacterOfPosition(parent.getStart(sourceFile));
            }
            /*
             * 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.isStatement(current)) &&
                    (parent.kind === 256 /* SourceFile */ || !parentAndChildShareLine);
                if (!useActualIndentation) {
                    return -1 /* Unknown */;
                }
                return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
            }
            function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) {
                var nextToken = ts.findNextToken(precedingToken, current);
                if (!nextToken) {
                    return false;
                }
                if (nextToken.kind === 15 /* OpenBraceToken */) {
                    // open braces are always indented at the parent level
                    return true;
                }
                else if (nextToken.kind === 16 /* 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;
                }
                return false;
            }
            function getStartLineAndCharacterForNode(n, sourceFile) {
                return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
            }
            function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) {
                if (parent.kind === 203 /* IfStatement */ && parent.elseStatement === child) {
                    var elseKeyword = ts.findChildOfKind(parent, 80 /* ElseKeyword */, sourceFile);
                    ts.Debug.assert(elseKeyword !== undefined);
                    var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
                    return elseKeywordStartLine === childStartLine;
                }
                return false;
            }
            SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement;
            function getContainingList(node, sourceFile) {
                if (node.parent) {
                    switch (node.parent.kind) {
                        case 155 /* TypeReference */:
                            if (node.parent.typeArguments &&
                                ts.rangeContainsStartEnd(node.parent.typeArguments, node.getStart(sourceFile), node.getEnd())) {
                                return node.parent.typeArguments;
                            }
                            break;
                        case 171 /* ObjectLiteralExpression */:
                            return node.parent.properties;
                        case 170 /* ArrayLiteralExpression */:
                            return node.parent.elements;
                        case 220 /* FunctionDeclaration */:
                        case 179 /* FunctionExpression */:
                        case 180 /* ArrowFunction */:
                        case 147 /* MethodDeclaration */:
                        case 146 /* MethodSignature */:
                        case 151 /* CallSignature */:
                        case 152 /* ConstructSignature */: {
                            var start = node.getStart(sourceFile);
                            if (node.parent.typeParameters &&
                                ts.rangeContainsStartEnd(node.parent.typeParameters, start, node.getEnd())) {
                                return node.parent.typeParameters;
                            }
                            if (ts.rangeContainsStartEnd(node.parent.parameters, start, node.getEnd())) {
                                return node.parent.parameters;
                            }
                            break;
                        }
                        case 175 /* NewExpression */:
                        case 174 /* CallExpression */: {
                            var start = node.getStart(sourceFile);
                            if (node.parent.typeArguments &&
                                ts.rangeContainsStartEnd(node.parent.typeArguments, start, node.getEnd())) {
                                return node.parent.typeArguments;
                            }
                            if (node.parent.arguments &&
                                ts.rangeContainsStartEnd(node.parent.arguments, start, node.getEnd())) {
                                return node.parent.arguments;
                            }
                            break;
                        }
                    }
                }
                return undefined;
            }
            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 === 18 /* CloseParenToken */) {
                    return -1 /* Unknown */;
                }
                if (node.parent && (node.parent.kind === 174 /* CallExpression */ ||
                    node.parent.kind === 175 /* NewExpression */) &&
                    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 174 /* CallExpression */:
                            case 175 /* NewExpression */:
                            case 172 /* PropertyAccessExpression */:
                            case 173 /* 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 === 24 /* 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 202 /* ExpressionStatement */:
                    case 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 222 /* InterfaceDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 223 /* TypeAliasDeclaration */:
                    case 170 /* ArrayLiteralExpression */:
                    case 199 /* Block */:
                    case 226 /* ModuleBlock */:
                    case 171 /* ObjectLiteralExpression */:
                    case 159 /* TypeLiteral */:
                    case 161 /* TupleType */:
                    case 227 /* CaseBlock */:
                    case 250 /* DefaultClause */:
                    case 249 /* CaseClause */:
                    case 178 /* ParenthesizedExpression */:
                    case 172 /* PropertyAccessExpression */:
                    case 174 /* CallExpression */:
                    case 175 /* NewExpression */:
                    case 200 /* VariableStatement */:
                    case 218 /* VariableDeclaration */:
                    case 235 /* ExportAssignment */:
                    case 211 /* ReturnStatement */:
                    case 188 /* ConditionalExpression */:
                    case 168 /* ArrayBindingPattern */:
                    case 167 /* ObjectBindingPattern */:
                    case 243 /* JsxOpeningElement */:
                    case 242 /* JsxSelfClosingElement */:
                    case 248 /* JsxExpression */:
                    case 146 /* MethodSignature */:
                    case 151 /* CallSignature */:
                    case 152 /* ConstructSignature */:
                    case 142 /* Parameter */:
                    case 156 /* FunctionType */:
                    case 157 /* ConstructorType */:
                    case 164 /* ParenthesizedType */:
                    case 176 /* TaggedTemplateExpression */:
                    case 184 /* AwaitExpression */:
                    case 237 /* NamedExports */:
                    case 233 /* NamedImports */:
                    case 238 /* ExportSpecifier */:
                    case 234 /* ImportSpecifier */:
                        return true;
                }
                return false;
            }
            /* @internal */
            function nodeWillIndentChild(parent, child, indentByDefault) {
                var childKind = child ? child.kind : 0 /* Unknown */;
                switch (parent.kind) {
                    case 204 /* DoStatement */:
                    case 205 /* WhileStatement */:
                    case 207 /* ForInStatement */:
                    case 208 /* ForOfStatement */:
                    case 206 /* ForStatement */:
                    case 203 /* IfStatement */:
                    case 220 /* FunctionDeclaration */:
                    case 179 /* FunctionExpression */:
                    case 147 /* MethodDeclaration */:
                    case 180 /* ArrowFunction */:
                    case 148 /* Constructor */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        return childKind !== 199 /* Block */;
                    case 236 /* ExportDeclaration */:
                        return childKind !== 237 /* NamedExports */;
                    case 230 /* ImportDeclaration */:
                        return childKind !== 231 /* ImportClause */ ||
                            (child.namedBindings && child.namedBindings.kind !== 233 /* NamedImports */);
                    case 241 /* JsxElement */:
                        return childKind !== 245 /* 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 = {}));
/// <reference path="..\compiler\program.ts"/>
/// <reference path="..\compiler\commandLineParser.ts"/>
/// <reference path='breakpoints.ts' />
/// <reference path='outliningElementsCollector.ts' />
/// <reference path='navigateTo.ts' />
/// <reference path='navigationBar.ts' />
/// <reference path='patternMatcher.ts' />
/// <reference path='signatureHelp.ts' />
/// <reference path='utilities.ts' />
/// <reference path='jsTyping.ts' />
/// <reference path='formatting\formatting.ts' />
/// <reference path='formatting\smartIndenter.ts' />
var ts;
(function (ts) {
    /** The version of the language service API */
    ts.servicesVersion = "0.5";
    var ScriptSnapshot;
    (function (ScriptSnapshot) {
        var StringScriptSnapshot = (function () {
            function StringScriptSnapshot(text) {
                this.text = text;
            }
            StringScriptSnapshot.prototype.getText = function (start, end) {
                return this.text.substring(start, end);
            };
            StringScriptSnapshot.prototype.getLength = function () {
                return this.text.length;
            };
            StringScriptSnapshot.prototype.getChangeRange = function (oldSnapshot) {
                // 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 scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true);
    var emptyArray = [];
    var jsDocTagNames = [
        "augments",
        "author",
        "argument",
        "borrows",
        "class",
        "constant",
        "constructor",
        "constructs",
        "default",
        "deprecated",
        "description",
        "event",
        "example",
        "extends",
        "field",
        "fileOverview",
        "function",
        "ignore",
        "inner",
        "lends",
        "link",
        "memberOf",
        "name",
        "namespace",
        "param",
        "private",
        "property",
        "public",
        "requires",
        "returns",
        "see",
        "since",
        "static",
        "throws",
        "type",
        "typedef",
        "property",
        "prop",
        "version"
    ];
    var jsDocCompletionEntries;
    function createNode(kind, pos, end, flags, parent) {
        var node = new NodeObject(kind, pos, end);
        node.flags = flags;
        node.parent = parent;
        return node;
    }
    var NodeObject = (function () {
        function NodeObject(kind, pos, end) {
            this.kind = kind;
            this.pos = pos;
            this.end = end;
            this.flags = 0 /* None */;
            this.parent = undefined;
        }
        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) {
            return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
        };
        NodeObject.prototype.addSyntheticNodes = function (nodes, pos, end, useJSDocScanner) {
            scanner.setTextPos(pos);
            while (pos < end) {
                var token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan();
                var textPos = scanner.getTextPos();
                if (textPos <= end) {
                    nodes.push(createNode(token, pos, textPos, 0, this));
                }
                pos = textPos;
            }
            return pos;
        };
        NodeObject.prototype.createSyntaxList = function (nodes) {
            var list = createNode(282 /* SyntaxList */, nodes.pos, nodes.end, 0, this);
            list._children = [];
            var pos = nodes.pos;
            for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) {
                var node = nodes_4[_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;
            var children;
            if (this.kind >= 139 /* FirstNode */) {
                scanner.setText((sourceFile || this.getSourceFile()).text);
                children = [];
                var pos_3 = this.pos;
                var useJSDocScanner_1 = this.kind >= 273 /* FirstJSDocTagNode */ && this.kind <= 281 /* LastJSDocTagNode */;
                var processNode = function (node) {
                    if (pos_3 < node.pos) {
                        pos_3 = _this.addSyntheticNodes(children, pos_3, node.pos, useJSDocScanner_1);
                    }
                    children.push(node);
                    pos_3 = node.end;
                };
                var processNodes = function (nodes) {
                    if (pos_3 < nodes.pos) {
                        pos_3 = _this.addSyntheticNodes(children, pos_3, nodes.pos, useJSDocScanner_1);
                    }
                    children.push(_this.createSyntaxList(nodes));
                    pos_3 = nodes.end;
                };
                // jsDocComments need to be the first children
                if (this.jsDocComments) {
                    for (var _i = 0, _a = this.jsDocComments; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        processNode(jsDocComment);
                    }
                }
                ts.forEachChild(this, processNode, processNodes);
                if (pos_3 < this.end) {
                    this.addSyntheticNodes(children, pos_3, this.end);
                }
                scanner.setText(undefined);
            }
            this._children = children || emptyArray;
        };
        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 = children[0];
            return child.kind < 139 /* 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 < 139 /* FirstNode */ ? child : child.getLastToken(sourceFile);
        };
        return NodeObject;
    }());
    var SymbolObject = (function () {
        function SymbolObject(flags, name) {
            this.flags = flags;
            this.name = name;
        }
        SymbolObject.prototype.getFlags = function () {
            return this.flags;
        };
        SymbolObject.prototype.getName = function () {
            return this.name;
        };
        SymbolObject.prototype.getDeclarations = function () {
            return this.declarations;
        };
        SymbolObject.prototype.getDocumentationComment = function () {
            if (this.documentationComment === undefined) {
                this.documentationComment = getJsDocCommentsFromDeclarations(this.declarations, this.name, !(this.flags & 4 /* Property */));
            }
            return this.documentationComment;
        };
        return SymbolObject;
    }());
    function getJsDocCommentsFromDeclarations(declarations, name, canUseParsedParamTagComments) {
        var documentationComment = [];
        var docComments = getJsDocCommentsSeparatedByNewLines();
        ts.forEach(docComments, function (docComment) {
            if (documentationComment.length) {
                documentationComment.push(ts.lineBreakPart());
            }
            documentationComment.push(docComment);
        });
        return documentationComment;
        function getJsDocCommentsSeparatedByNewLines() {
            var paramTag = "@param";
            var jsDocCommentParts = [];
            ts.forEach(declarations, function (declaration, indexOfDeclaration) {
                // Make sure we are collecting doc comment from declaration once,
                // In case of 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>
                if (ts.indexOf(declarations, declaration) === indexOfDeclaration) {
                    var sourceFileOfDeclaration = ts.getSourceFileOfNode(declaration);
                    // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments
                    if (canUseParsedParamTagComments && declaration.kind === 142 /* Parameter */) {
                        if ((declaration.parent.kind === 179 /* FunctionExpression */ || declaration.parent.kind === 180 /* ArrowFunction */) &&
                            declaration.parent.parent.kind === 218 /* VariableDeclaration */) {
                            addCommentParts(declaration.parent.parent.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment);
                        }
                        addCommentParts(declaration.parent, sourceFileOfDeclaration, getCleanedParamJsDocComment);
                    }
                    // If this is left side of dotted module declaration, there is no doc comments associated with this node
                    if (declaration.kind === 225 /* ModuleDeclaration */ && declaration.body && declaration.body.kind === 225 /* ModuleDeclaration */) {
                        return;
                    }
                    if ((declaration.kind === 179 /* FunctionExpression */ || declaration.kind === 180 /* ArrowFunction */) &&
                        declaration.parent.kind === 218 /* VariableDeclaration */) {
                        addCommentParts(declaration.parent.parent, sourceFileOfDeclaration, getCleanedJsDocComment);
                    }
                    // If this is dotted module name, get the doc comments from the parent
                    while (declaration.kind === 225 /* ModuleDeclaration */ && declaration.parent.kind === 225 /* ModuleDeclaration */) {
                        declaration = declaration.parent;
                    }
                    addCommentParts(declaration.kind === 218 /* VariableDeclaration */ ? declaration.parent.parent : declaration, sourceFileOfDeclaration, getCleanedJsDocComment);
                    if (declaration.kind === 218 /* VariableDeclaration */) {
                        var init = declaration.initializer;
                        if (init && (init.kind === 179 /* FunctionExpression */ || init.kind === 180 /* ArrowFunction */)) {
                            // Get the cleaned js doc comment text from the initializer
                            addCommentParts(init, sourceFileOfDeclaration, getCleanedJsDocComment);
                        }
                    }
                }
            });
            return jsDocCommentParts;
            function addCommentParts(commented, sourceFileOfDeclaration, getCommentPart) {
                var ranges = getJsDocCommentTextRange(commented, sourceFileOfDeclaration);
                // Get the cleaned js doc comment text from the declaration
                ts.forEach(ranges, function (jsDocCommentTextRange) {
                    var cleanedComment = getCommentPart(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration);
                    if (cleanedComment) {
                        ts.addRange(jsDocCommentParts, cleanedComment);
                    }
                });
            }
            function getJsDocCommentTextRange(node, sourceFile) {
                return ts.map(ts.getJsDocComments(node, sourceFile), function (jsDocComment) {
                    return {
                        pos: jsDocComment.pos + "/*".length,
                        end: jsDocComment.end - "*/".length // Trim off comment end indicator
                    };
                });
            }
            function consumeWhiteSpacesOnTheLine(pos, end, sourceFile, maxSpacesToRemove) {
                if (maxSpacesToRemove !== undefined) {
                    end = Math.min(end, pos + maxSpacesToRemove);
                }
                for (; pos < end; pos++) {
                    var ch = sourceFile.text.charCodeAt(pos);
                    if (!ts.isWhiteSpaceSingleLine(ch)) {
                        return pos;
                    }
                }
                return end;
            }
            function consumeLineBreaks(pos, end, sourceFile) {
                while (pos < end && ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                    pos++;
                }
                return pos;
            }
            function isName(pos, end, sourceFile, name) {
                return pos + name.length < end &&
                    sourceFile.text.substr(pos, name.length) === name &&
                    ts.isWhiteSpace(sourceFile.text.charCodeAt(pos + name.length));
            }
            function isParamTag(pos, end, sourceFile) {
                // If it is @param tag
                return isName(pos, end, sourceFile, paramTag);
            }
            function pushDocCommentLineText(docComments, text, blankLineCount) {
                // Add the empty lines in between texts
                while (blankLineCount) {
                    blankLineCount--;
                    docComments.push(ts.textPart(""));
                }
                docComments.push(ts.textPart(text));
            }
            function getCleanedJsDocComment(pos, end, sourceFile) {
                var spacesToRemoveAfterAsterisk;
                var docComments = [];
                var blankLineCount = 0;
                var isInParamTag = false;
                while (pos < end) {
                    var docCommentTextOfLine = "";
                    // First consume leading white space
                    pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile);
                    // If the comment starts with '*' consume the spaces on this line
                    if (pos < end && sourceFile.text.charCodeAt(pos) === 42 /* asterisk */) {
                        var lineStartPos = pos + 1;
                        pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk);
                        // Set the spaces to remove after asterisk as margin if not already set
                        if (spacesToRemoveAfterAsterisk === undefined && pos < end && !ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                            spacesToRemoveAfterAsterisk = pos - lineStartPos;
                        }
                    }
                    else if (spacesToRemoveAfterAsterisk === undefined) {
                        spacesToRemoveAfterAsterisk = 0;
                    }
                    // Analyze text on this line
                    while (pos < end && !ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                        var ch = sourceFile.text.charAt(pos);
                        if (ch === "@") {
                            // If it is @param tag
                            if (isParamTag(pos, end, sourceFile)) {
                                isInParamTag = true;
                                pos += paramTag.length;
                                continue;
                            }
                            else {
                                isInParamTag = false;
                            }
                        }
                        // Add the ch to doc text if we arent in param tag
                        if (!isInParamTag) {
                            docCommentTextOfLine += ch;
                        }
                        // Scan next character
                        pos++;
                    }
                    // Continue with next line
                    pos = consumeLineBreaks(pos, end, sourceFile);
                    if (docCommentTextOfLine) {
                        pushDocCommentLineText(docComments, docCommentTextOfLine, blankLineCount);
                        blankLineCount = 0;
                    }
                    else if (!isInParamTag && docComments.length) {
                        // This is blank line when there is text already parsed
                        blankLineCount++;
                    }
                }
                return docComments;
            }
            function getCleanedParamJsDocComment(pos, end, sourceFile) {
                var paramHelpStringMargin;
                var paramDocComments = [];
                while (pos < end) {
                    if (isParamTag(pos, end, sourceFile)) {
                        var blankLineCount = 0;
                        var recordedParamTag = false;
                        // Consume leading spaces
                        pos = consumeWhiteSpaces(pos + paramTag.length);
                        if (pos >= end) {
                            break;
                        }
                        // Ignore type expression
                        if (sourceFile.text.charCodeAt(pos) === 123 /* openBrace */) {
                            pos++;
                            for (var curlies = 1; pos < end; pos++) {
                                var charCode = sourceFile.text.charCodeAt(pos);
                                // { character means we need to find another } to match the found one
                                if (charCode === 123 /* openBrace */) {
                                    curlies++;
                                    continue;
                                }
                                // } char
                                if (charCode === 125 /* closeBrace */) {
                                    curlies--;
                                    if (curlies === 0) {
                                        // We do not have any more } to match the type expression is ignored completely
                                        pos++;
                                        break;
                                    }
                                    else {
                                        // there are more { to be matched with }
                                        continue;
                                    }
                                }
                                // Found start of another tag
                                if (charCode === 64 /* at */) {
                                    break;
                                }
                            }
                            // Consume white spaces
                            pos = consumeWhiteSpaces(pos);
                            if (pos >= end) {
                                break;
                            }
                        }
                        // Parameter name
                        if (isName(pos, end, sourceFile, name)) {
                            // Found the parameter we are looking for consume white spaces
                            pos = consumeWhiteSpaces(pos + name.length);
                            if (pos >= end) {
                                break;
                            }
                            var paramHelpString = "";
                            var firstLineParamHelpStringPos = pos;
                            while (pos < end) {
                                var ch = sourceFile.text.charCodeAt(pos);
                                // at line break, set this comment line text and go to next line
                                if (ts.isLineBreak(ch)) {
                                    if (paramHelpString) {
                                        pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount);
                                        paramHelpString = "";
                                        blankLineCount = 0;
                                        recordedParamTag = true;
                                    }
                                    else if (recordedParamTag) {
                                        blankLineCount++;
                                    }
                                    // Get the pos after cleaning start of the line
                                    setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos);
                                    continue;
                                }
                                // Done scanning param help string - next tag found
                                if (ch === 64 /* at */) {
                                    break;
                                }
                                paramHelpString += sourceFile.text.charAt(pos);
                                // Go to next character
                                pos++;
                            }
                            // If there is param help text, add it top the doc comments
                            if (paramHelpString) {
                                pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount);
                            }
                            paramHelpStringMargin = undefined;
                        }
                        // If this is the start of another tag, continue with the loop in search of param tag with symbol name
                        if (sourceFile.text.charCodeAt(pos) === 64 /* at */) {
                            continue;
                        }
                    }
                    // Next character
                    pos++;
                }
                return paramDocComments;
                function consumeWhiteSpaces(pos) {
                    while (pos < end && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) {
                        pos++;
                    }
                    return pos;
                }
                function setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos) {
                    // Get the pos after consuming line breaks
                    pos = consumeLineBreaks(pos, end, sourceFile);
                    if (pos >= end) {
                        return;
                    }
                    if (paramHelpStringMargin === undefined) {
                        paramHelpStringMargin = sourceFile.getLineAndCharacterOfPosition(firstLineParamHelpStringPos).character;
                    }
                    // Now consume white spaces max
                    var startOfLinePos = pos;
                    pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin);
                    if (pos >= end) {
                        return;
                    }
                    var consumedSpaces = pos - startOfLinePos;
                    if (consumedSpaces < paramHelpStringMargin) {
                        var ch = sourceFile.text.charCodeAt(pos);
                        if (ch === 42 /* asterisk */) {
                            // Consume more spaces after asterisk
                            pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1);
                        }
                    }
                }
            }
        }
    }
    var TypeObject = (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 & (1024 /* Class */ | 2048 /* Interface */)
                ? this.checker.getBaseTypes(this)
                : undefined;
        };
        TypeObject.prototype.getNonNullableType = function () {
            return this.checker.getNonNullableType(this);
        };
        return TypeObject;
    }());
    var SignatureObject = (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 ? getJsDocCommentsFromDeclarations([this.declaration], 
                /*name*/ undefined, 
                /*canUseParsedParamTagComments*/ false) : [];
            }
            return this.documentationComment;
        };
        return SignatureObject;
    }());
    var SourceFileObject = (function (_super) {
        __extends(SourceFileObject, _super);
        function SourceFileObject(kind, pos, end) {
            _super.call(this, kind, pos, end);
        }
        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.getNamedDeclarations = function () {
            if (!this.namedDeclarations) {
                this.namedDeclarations = this.computeNamedDeclarations();
            }
            return this.namedDeclarations;
        };
        SourceFileObject.prototype.computeNamedDeclarations = function () {
            var result = {};
            ts.forEachChild(this, visit);
            return result;
            function addDeclaration(declaration) {
                var name = getDeclarationName(declaration);
                if (name) {
                    var declarations = getDeclarations(name);
                    declarations.push(declaration);
                }
            }
            function getDeclarations(name) {
                return ts.getProperty(result, name) || (result[name] = []);
            }
            function getDeclarationName(declaration) {
                if (declaration.name) {
                    var result_2 = getTextOfIdentifierOrLiteral(declaration.name);
                    if (result_2 !== undefined) {
                        return result_2;
                    }
                    if (declaration.name.kind === 140 /* ComputedPropertyName */) {
                        var expr = declaration.name.expression;
                        if (expr.kind === 172 /* PropertyAccessExpression */) {
                            return expr.name.text;
                        }
                        return getTextOfIdentifierOrLiteral(expr);
                    }
                }
                return undefined;
            }
            function getTextOfIdentifierOrLiteral(node) {
                if (node) {
                    if (node.kind === 69 /* Identifier */ ||
                        node.kind === 9 /* StringLiteral */ ||
                        node.kind === 8 /* NumericLiteral */) {
                        return node.text;
                    }
                }
                return undefined;
            }
            function visit(node) {
                switch (node.kind) {
                    case 220 /* FunctionDeclaration */:
                    case 179 /* FunctionExpression */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* 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 221 /* ClassDeclaration */:
                    case 192 /* ClassExpression */:
                    case 222 /* InterfaceDeclaration */:
                    case 223 /* TypeAliasDeclaration */:
                    case 224 /* EnumDeclaration */:
                    case 225 /* ModuleDeclaration */:
                    case 229 /* ImportEqualsDeclaration */:
                    case 238 /* ExportSpecifier */:
                    case 234 /* ImportSpecifier */:
                    case 229 /* ImportEqualsDeclaration */:
                    case 231 /* ImportClause */:
                    case 232 /* NamespaceImport */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 159 /* TypeLiteral */:
                        addDeclaration(node);
                        ts.forEachChild(node, visit);
                        break;
                    case 142 /* Parameter */:
                        // Only consider parameter properties
                        if (!(node.flags & 92 /* ParameterPropertyModifier */)) {
                            break;
                        }
                    // fall through
                    case 218 /* VariableDeclaration */:
                    case 169 /* BindingElement */: {
                        var decl = node;
                        if (ts.isBindingPattern(decl.name)) {
                            ts.forEachChild(decl.name, visit);
                            break;
                        }
                        if (decl.initializer)
                            visit(decl.initializer);
                    }
                    case 255 /* EnumMember */:
                    case 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                        addDeclaration(node);
                        break;
                    case 236 /* 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 230 /* 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 === 232 /* NamespaceImport */) {
                                    addDeclaration(importClause.namedBindings);
                                }
                                else {
                                    ts.forEach(importClause.namedBindings.elements, visit);
                                }
                            }
                        }
                        break;
                    default:
                        ts.forEachChild(node, visit);
                }
            }
        };
        return SourceFileObject;
    }(NodeObject));
    var TextChange = (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 = {}));
    (function (IndentStyle) {
        IndentStyle[IndentStyle["None"] = 0] = "None";
        IndentStyle[IndentStyle["Block"] = 1] = "Block";
        IndentStyle[IndentStyle["Smart"] = 2] = "Smart";
    })(ts.IndentStyle || (ts.IndentStyle = {}));
    var IndentStyle = ts.IndentStyle;
    (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";
    })(ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {}));
    var SymbolDisplayPartKind = ts.SymbolDisplayPartKind;
    (function (OutputFileType) {
        OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
        OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
        OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
    })(ts.OutputFileType || (ts.OutputFileType = {}));
    var OutputFileType = ts.OutputFileType;
    (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";
    })(ts.EndOfLineState || (ts.EndOfLineState = {}));
    var EndOfLineState = ts.EndOfLineState;
    (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";
    })(ts.TokenClass || (ts.TokenClass = {}));
    var TokenClass = ts.TokenClass;
    // TODO: move these to enums
    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";
        /**
         * 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 = 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 () {
        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";
        return ClassificationTypeNames;
    }());
    ts.ClassificationTypeNames = ClassificationTypeNames;
    (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";
    })(ts.ClassificationType || (ts.ClassificationType = {}));
    var ClassificationType = ts.ClassificationType;
    function displayPartsToString(displayParts) {
        if (displayParts) {
            return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join("");
        }
        return "";
    }
    ts.displayPartsToString = displayPartsToString;
    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 === 179 /* FunctionExpression */) {
                return true;
            }
            if (declaration.kind !== 218 /* VariableDeclaration */ && declaration.kind !== 220 /* FunctionDeclaration */) {
                return false;
            }
            // If the parent is not sourceFile or module block it is local variable
            for (var parent_16 = declaration.parent; !ts.isFunctionBlock(parent_16); parent_16 = parent_16.parent) {
                // Reached source file or module block
                if (parent_16.kind === 256 /* SourceFile */ || parent_16.kind === 226 /* ModuleBlock */) {
                    return false;
                }
            }
            // parent is in function block
            return true;
        });
    }
    function getDefaultCompilerOptions() {
        // Always default to "ScriptTarget.ES5" for the language service
        return {
            target: 1 /* ES5 */,
            jsx: 1 /* Preserve */
        };
    }
    ts.getDefaultCompilerOptions = getDefaultCompilerOptions;
    // Cache host information about scrip Should be refreshed
    // at each language service public entry point, since we don't know when
    // set of scripts handled by the host changes.
    var HostCache = (function () {
        function HostCache(host, getCanonicalFileName) {
            this.host = host;
            this.getCanonicalFileName = getCanonicalFileName;
            // script id => script index
            this.currentDirectory = host.getCurrentDirectory();
            this.fileNameToEntry = ts.createFileMap();
            // 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)
                };
            }
            this.fileNameToEntry.set(path, entry);
            return entry;
        };
        HostCache.prototype.getEntry = function (path) {
            return this.fileNameToEntry.get(path);
        };
        HostCache.prototype.contains = function (path) {
            return this.fileNameToEntry.contains(path);
        };
        HostCache.prototype.getOrCreateEntry = function (fileName) {
            var path = ts.toPath(fileName, this.currentDirectory, this.getCanonicalFileName);
            return this.getOrCreateEntryByPath(fileName, path);
        };
        HostCache.prototype.getOrCreateEntryByPath = function (fileName, path) {
            return this.contains(path)
                ? this.getEntry(path)
                : this.createEntry(fileName, path);
        };
        HostCache.prototype.getRootFileNames = function () {
            var fileNames = [];
            this.fileNameToEntry.forEachValue(function (path, value) {
                if (value) {
                    fileNames.push(value.hostFileName);
                }
            });
            return fileNames;
        };
        HostCache.prototype.getVersion = function (path) {
            var file = this.getEntry(path);
            return file && file.version;
        };
        HostCache.prototype.getScriptSnapshot = function (path) {
            var file = this.getEntry(path);
            return file && file.scriptSnapshot;
        };
        return HostCache;
    }());
    var SyntaxTreeCache = (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, 2 /* 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;
    }
    var commandLineOptionsStringToEnum;
    /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
    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.forEachValue(o.type, function (v) { return typeof v !== "number"; });
        });
        options = ts.clone(options);
        var _loop_3 = function(opt) {
            if (!ts.hasProperty(options, opt.name)) {
                return "continue";
            }
            var value = options[opt.name];
            // Value should be a key of opt.type
            if (typeof value === "string") {
                // If value is not a string, this will fail
                options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics);
            }
            else {
                if (!ts.forEachValue(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_3(opt);
        }
        return options;
    }
    /*
     * 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) : 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;
        }
        sourceFile.renamedDependencies = 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, target) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; },
            writeFile: function (name, text, writeByteOrderMark) {
                if (ts.fileExtensionIs(name, ".map")) {
                    ts.Debug.assert(sourceMapText === undefined, "Unexpected multiple source map outputs for the file '" + name + "'");
                    sourceMapText = text;
                }
                else {
                    ts.Debug.assert(outputText === undefined, "Unexpected multiple outputs for the 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 (fileName) { return ""; },
            directoryExists: function (directoryExists) { return true; },
            getDirectories: function (path) { 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();
        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;
    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;
    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 = {};
        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 = ts.lookUp(buckets, key);
            if (!bucket && createIfMissing) {
                buckets[key] = bucket = ts.createFileMap();
            }
            return bucket;
        }
        function reportStats() {
            var bucketInfoArray = Object.keys(buckets).filter(function (name) { return name && name.charAt(0) === "_"; }).map(function (name) {
                var entries = ts.lookUp(buckets, name);
                var sourceFiles = [];
                entries.forEachValue(function (key, entry) {
                    sourceFiles.push({
                        name: key,
                        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) {
                ts.Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
                // Have never seen this file with these settings.  Create a new source file for it.
                var sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
                entry = {
                    sourceFile: sourceFile,
                    languageServiceRefCount: 0,
                    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 = 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.remove(path);
            }
        }
        return {
            acquireDocument: acquireDocument,
            acquireDocumentWithKey: acquireDocumentWithKey,
            updateDocument: updateDocument,
            updateDocumentWithKey: updateDocumentWithKey,
            releaseDocument: releaseDocument,
            releaseDocumentWithKey: releaseDocumentWithKey,
            reportStats: reportStats,
            getKeyForCompilationSettings: getKeyForCompilationSettings
        };
    }
    ts.createDocumentRegistry = createDocumentRegistry;
    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 = scanner.scan();
            if (token === 15 /* OpenBraceToken */) {
                braceNesting++;
            }
            else if (token === 16 /* 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 file = scanner.getTokenValue();
            var pos = scanner.getTokenPos();
            return {
                fileName: file,
                pos: pos,
                end: pos + file.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 = scanner.getToken();
            if (token === 122 /* DeclareKeyword */) {
                // declare module "mod"
                token = nextToken();
                if (token === 125 /* 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 = scanner.getToken();
            if (token === 89 /* ImportKeyword */) {
                token = nextToken();
                if (token === 9 /* StringLiteral */) {
                    // import "mod";
                    recordModuleName();
                    return true;
                }
                else {
                    if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 136 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 9 /* StringLiteral */) {
                                // import d from "mod";
                                recordModuleName();
                                return true;
                            }
                        }
                        else if (token === 56 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                        else if (token === 24 /* CommaToken */) {
                            // consume comma and keep going
                            token = nextToken();
                        }
                        else {
                            // unknown syntax
                            return true;
                        }
                    }
                    if (token === 15 /* OpenBraceToken */) {
                        token = nextToken();
                        // consume "{ a as B, c, d as D}" clauses
                        // make sure that it stops on EOF
                        while (token !== 16 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                            token = nextToken();
                        }
                        if (token === 16 /* CloseBraceToken */) {
                            token = nextToken();
                            if (token === 136 /* 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 === 37 /* AsteriskToken */) {
                        token = nextToken();
                        if (token === 116 /* AsKeyword */) {
                            token = nextToken();
                            if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
                                token = nextToken();
                                if (token === 136 /* 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 = scanner.getToken();
            if (token === 82 /* ExportKeyword */) {
                markAsExternalModuleIfTopLevel();
                token = nextToken();
                if (token === 15 /* OpenBraceToken */) {
                    token = nextToken();
                    // consume "{ a as B, c, d as D}" clauses
                    // make sure it stops on EOF
                    while (token !== 16 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) {
                        token = nextToken();
                    }
                    if (token === 16 /* CloseBraceToken */) {
                        token = nextToken();
                        if (token === 136 /* FromKeyword */) {
                            token = nextToken();
                            if (token === 9 /* StringLiteral */) {
                                // export {a as A} from "mod";
                                // export {a, b as B} from "mod"
                                recordModuleName();
                            }
                        }
                    }
                }
                else if (token === 37 /* AsteriskToken */) {
                    token = nextToken();
                    if (token === 136 /* FromKeyword */) {
                        token = nextToken();
                        if (token === 9 /* StringLiteral */) {
                            // export * from "mod"
                            recordModuleName();
                        }
                    }
                }
                else if (token === 89 /* ImportKeyword */) {
                    token = nextToken();
                    if (token === 69 /* Identifier */ || ts.isKeyword(token)) {
                        token = nextToken();
                        if (token === 56 /* EqualsToken */) {
                            if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
                                return true;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeRequireCall(skipCurrentToken) {
            var token = skipCurrentToken ? nextToken() : scanner.getToken();
            if (token === 129 /* RequireKeyword */) {
                token = nextToken();
                if (token === 17 /* OpenParenToken */) {
                    token = nextToken();
                    if (token === 9 /* StringLiteral */) {
                        //  require("mod");
                        recordModuleName();
                    }
                }
                return true;
            }
            return false;
        }
        function tryConsumeDefine() {
            var token = scanner.getToken();
            if (token === 69 /* Identifier */ && scanner.getTokenValue() === "define") {
                token = nextToken();
                if (token !== 17 /* OpenParenToken */) {
                    return true;
                }
                token = nextToken();
                if (token === 9 /* StringLiteral */) {
                    // looks like define ("modname", ... - skip string literal and comma
                    token = nextToken();
                    if (token === 24 /* CommaToken */) {
                        token = nextToken();
                    }
                    else {
                        // unexpected token
                        return true;
                    }
                }
                // should be start of dependency list
                if (token !== 19 /* OpenBracketToken */) {
                    return true;
                }
                // skip open bracket
                token = nextToken();
                var i = 0;
                // scan until ']' or EOF
                while (token !== 20 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) {
                    // record string literals as module names
                    if (token === 9 /* StringLiteral */) {
                        recordModuleName();
                        i++;
                    }
                    token = nextToken();
                }
                return true;
            }
            return false;
        }
        function processImports() {
            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");
            //
            //    export * from "mod"
            //    export {a as b} from "mod"
            //    export import i = require("mod")
            //    (for JavaScript files) require("mod")
            while (true) {
                if (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();
                }
            }
            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;
    /// Helpers
    function getTargetLabel(referenceNode, labelName) {
        while (referenceNode) {
            if (referenceNode.kind === 214 /* LabeledStatement */ && referenceNode.label.text === labelName) {
                return referenceNode.label;
            }
            referenceNode = referenceNode.parent;
        }
        return undefined;
    }
    function isJumpStatementTarget(node) {
        return node.kind === 69 /* Identifier */ &&
            (node.parent.kind === 210 /* BreakStatement */ || node.parent.kind === 209 /* ContinueStatement */) &&
            node.parent.label === node;
    }
    function isLabelOfLabeledStatement(node) {
        return node.kind === 69 /* Identifier */ &&
            node.parent.kind === 214 /* LabeledStatement */ &&
            node.parent.label === node;
    }
    /**
     * 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 === 214 /* LabeledStatement */; owner = owner.parent) {
            if (owner.label.text === labelName) {
                return true;
            }
        }
        return false;
    }
    function isLabelName(node) {
        return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
    }
    function isRightSideOfQualifiedName(node) {
        return node.parent.kind === 139 /* QualifiedName */ && node.parent.right === node;
    }
    function isRightSideOfPropertyAccess(node) {
        return node && node.parent && node.parent.kind === 172 /* PropertyAccessExpression */ && node.parent.name === node;
    }
    function isCallExpressionTarget(node) {
        if (isRightSideOfPropertyAccess(node)) {
            node = node.parent;
        }
        return node && node.parent && node.parent.kind === 174 /* CallExpression */ && node.parent.expression === node;
    }
    function isNewExpressionTarget(node) {
        if (isRightSideOfPropertyAccess(node)) {
            node = node.parent;
        }
        return node && node.parent && node.parent.kind === 175 /* NewExpression */ && node.parent.expression === node;
    }
    function isNameOfModuleDeclaration(node) {
        return node.parent.kind === 225 /* ModuleDeclaration */ && node.parent.name === node;
    }
    function isNameOfFunctionDeclaration(node) {
        return node.kind === 69 /* Identifier */ &&
            ts.isFunctionLike(node.parent) && node.parent.name === node;
    }
    function isObjectLiteralPropertyDeclaration(node) {
        switch (node.kind) {
            case 253 /* PropertyAssignment */:
            case 254 /* ShorthandPropertyAssignment */:
            case 147 /* MethodDeclaration */:
            case 149 /* GetAccessor */:
            case 150 /* SetAccessor */:
                return true;
        }
        return false;
    }
    /**
     * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
     */
    function getContainingObjectLiteralElement(node) {
        switch (node.kind) {
            case 9 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                if (node.parent.kind === 140 /* ComputedPropertyName */) {
                    return isObjectLiteralPropertyDeclaration(node.parent.parent) ? node.parent.parent : undefined;
                }
            // intential fall through
            case 69 /* Identifier */:
                return isObjectLiteralPropertyDeclaration(node.parent) && node.parent.name === node ? node.parent : undefined;
        }
        return undefined;
    }
    function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) {
        if (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) {
            switch (node.parent.kind) {
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 253 /* PropertyAssignment */:
                case 255 /* EnumMember */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 225 /* ModuleDeclaration */:
                    return node.parent.name === node;
                case 173 /* ElementAccessExpression */:
                    return node.parent.argumentExpression === node;
                case 140 /* ComputedPropertyName */:
                    return true;
            }
        }
        return false;
    }
    function isNameOfExternalModuleImportOrDeclaration(node) {
        if (node.kind === 9 /* StringLiteral */) {
            return isNameOfModuleDeclaration(node) ||
                (ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node);
        }
        return false;
    }
    /** Returns true if the position is within a comment */
    function isInsideComment(sourceFile, token, position) {
        // The position has to be: 1. in the leading trivia (before token.getStart()), and 2. within a comment
        return position <= token.getStart(sourceFile) &&
            (isInsideCommentRange(ts.getTrailingCommentRanges(sourceFile.text, token.getFullStart())) ||
                isInsideCommentRange(ts.getLeadingCommentRanges(sourceFile.text, token.getFullStart())));
        function isInsideCommentRange(comments) {
            return ts.forEach(comments, function (comment) {
                // either we are 1. completely inside the comment, or 2. at the end of the comment
                if (comment.pos < position && position < comment.end) {
                    return true;
                }
                else if (position === comment.end) {
                    var text = sourceFile.text;
                    var width = comment.end - comment.pos;
                    // is single line comment or just /*
                    if (width <= 2 || text.charCodeAt(comment.pos + 1) === 47 /* slash */) {
                        return true;
                    }
                    else {
                        // is unterminated multi-line comment
                        return !(text.charCodeAt(comment.end - 1) === 47 /* slash */ &&
                            text.charCodeAt(comment.end - 2) === 42 /* asterisk */);
                    }
                }
                return false;
            });
        }
    }
    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 || (SemanticMeaning = {}));
    var BreakContinueSearchType;
    (function (BreakContinueSearchType) {
        BreakContinueSearchType[BreakContinueSearchType["None"] = 0] = "None";
        BreakContinueSearchType[BreakContinueSearchType["Unlabeled"] = 1] = "Unlabeled";
        BreakContinueSearchType[BreakContinueSearchType["Labeled"] = 2] = "Labeled";
        BreakContinueSearchType[BreakContinueSearchType["All"] = 3] = "All";
    })(BreakContinueSearchType || (BreakContinueSearchType = {}));
    // A cache of completion entries for keywords, these do not change between sessions
    var keywordCompletions = [];
    for (var i = 70 /* FirstKeyword */; i <= 138 /* LastKeyword */; i++) {
        keywordCompletions.push({
            name: ts.tokenToString(i),
            kind: ScriptElementKind.keyword,
            kindModifiers: ScriptElementKindModifier.none,
            sortText: "0"
        });
    }
    /* @internal */ function getContainerNode(node) {
        while (true) {
            node = node.parent;
            if (!node) {
                return undefined;
            }
            switch (node.kind) {
                case 256 /* SourceFile */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 221 /* ClassDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 224 /* EnumDeclaration */:
                case 225 /* ModuleDeclaration */:
                    return node;
            }
        }
    }
    ts.getContainerNode = getContainerNode;
    /* @internal */ function getNodeKind(node) {
        switch (node.kind) {
            case 225 /* ModuleDeclaration */: return ScriptElementKind.moduleElement;
            case 221 /* ClassDeclaration */:
            case 192 /* ClassExpression */:
                return ScriptElementKind.classElement;
            case 222 /* InterfaceDeclaration */: return ScriptElementKind.interfaceElement;
            case 223 /* TypeAliasDeclaration */: return ScriptElementKind.typeElement;
            case 224 /* EnumDeclaration */: return ScriptElementKind.enumElement;
            case 218 /* VariableDeclaration */:
                return ts.isConst(node)
                    ? ScriptElementKind.constElement
                    : ts.isLet(node)
                        ? ScriptElementKind.letElement
                        : ScriptElementKind.variableElement;
            case 220 /* FunctionDeclaration */:
            case 179 /* FunctionExpression */:
                return ScriptElementKind.functionElement;
            case 149 /* GetAccessor */: return ScriptElementKind.memberGetAccessorElement;
            case 150 /* SetAccessor */: return ScriptElementKind.memberSetAccessorElement;
            case 147 /* MethodDeclaration */:
            case 146 /* MethodSignature */:
                return ScriptElementKind.memberFunctionElement;
            case 145 /* PropertyDeclaration */:
            case 144 /* PropertySignature */:
                return ScriptElementKind.memberVariableElement;
            case 153 /* IndexSignature */: return ScriptElementKind.indexSignatureElement;
            case 152 /* ConstructSignature */: return ScriptElementKind.constructSignatureElement;
            case 151 /* CallSignature */: return ScriptElementKind.callSignatureElement;
            case 148 /* Constructor */: return ScriptElementKind.constructorImplementationElement;
            case 141 /* TypeParameter */: return ScriptElementKind.typeParameterElement;
            case 255 /* EnumMember */: return ScriptElementKind.variableElement;
            case 142 /* Parameter */: return (node.flags & 92 /* ParameterPropertyModifier */) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement;
            case 229 /* ImportEqualsDeclaration */:
            case 234 /* ImportSpecifier */:
            case 231 /* ImportClause */:
            case 238 /* ExportSpecifier */:
            case 232 /* NamespaceImport */:
                return ScriptElementKind.alias;
        }
        return ScriptElementKind.unknown;
    }
    ts.getNodeKind = getNodeKind;
    var CancellationTokenObject = (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;
    }());
    function createLanguageService(host, documentRegistry) {
        if (documentRegistry === void 0) { documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); }
        var syntaxTreeCache = new SyntaxTreeCache(host);
        var ruleProvider;
        var program;
        var lastProjectVersion;
        var useCaseSensitivefileNames = false;
        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) {
            // Ensure rules are initialized and up to date wrt to formatting options
            if (!ruleProvider) {
                ruleProvider = new ts.formatting.RulesProvider();
            }
            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) {
                        return;
                    }
                    lastProjectVersion = hostProjectVersion;
                }
            }
            // Get a fresh cache of the host information
            var hostCache = new HostCache(host, getCanonicalFileName);
            // If the program is already up-to-date, we can reuse it
            if (programUpToDate()) {
                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 oldSettings = program && program.getCompilerOptions();
            var newSettings = hostCache.compilationSettings();
            var changesInCompilationSettingsAffectSyntax = oldSettings &&
                (oldSettings.target !== newSettings.target ||
                    oldSettings.module !== newSettings.module ||
                    oldSettings.moduleResolution !== newSettings.moduleResolution ||
                    oldSettings.noResolve !== newSettings.noResolve ||
                    oldSettings.jsx !== newSettings.jsx ||
                    oldSettings.allowJs !== newSettings.allowJs ||
                    oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit);
            // 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.getNewLineOrDefaultFromHost(host); },
                getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
                writeFile: function (fileName, data, writeByteOrderMark) { },
                getCurrentDirectory: function () { return currentDirectory; },
                fileExists: function (fileName) {
                    // stub missing host functionality
                    ts.Debug.assert(!host.resolveModuleNames || !host.resolveTypeReferenceDirectives);
                    return hostCache.getOrCreateEntry(fileName) !== undefined;
                },
                readFile: function (fileName) {
                    // stub missing host functionality
                    var entry = hostCache.getOrCreateEntry(fileName);
                    return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength());
                },
                directoryExists: function (directoryName) {
                    return ts.directoryProbablyExists(directoryName, host);
                },
                getDirectories: function (path) {
                    return host.getDirectories ? host.getDirectories(path) : [];
                }
            };
            if (host.trace) {
                compilerHost.trace = function (message) { return host.trace(message); };
            }
            if (host.resolveModuleNames) {
                compilerHost.resolveModuleNames = function (moduleNames, containingFile) { return host.resolveModuleNames(moduleNames, containingFile); };
            }
            if (host.resolveTypeReferenceDirectives) {
                compilerHost.resolveTypeReferenceDirectives = function (typeReferenceDirectiveNames, containingFile) {
                    return host.resolveTypeReferenceDirectives(typeReferenceDirectiveNames, containingFile);
                };
            }
            var documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
            var newProgram = ts.createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program);
            // Release any files we have acquired in the old program but are
            // not part of the new program.
            if (program) {
                var oldSourceFiles = program.getSourceFiles();
                var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings);
                for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) {
                    var oldSourceFile = oldSourceFiles_1[_i];
                    if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) {
                        documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey);
                    }
                }
            }
            // 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;
            program = newProgram;
            // Make sure all the nodes in the program are both bound, and have their parent
            // pointers set property.
            program.getTypeChecker();
            return;
            function getOrCreateSourceFile(fileName) {
                return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName));
            }
            function getOrCreateSourceFileByPath(fileName, path) {
                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 (!changesInCompilationSettingsAffectSyntax) {
                    // 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.assert(hostFileInformation.scriptKind === oldSourceFile.scriptKind, "Registered script kind (" + oldSourceFile.scriptKind + ") should match new script kind (" + hostFileInformation.scriptKind + ") for file: " + path);
                        return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
                    }
                }
                // 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 sourceFileUpToDate(sourceFile) {
                if (!sourceFile) {
                    return false;
                }
                var path = sourceFile.path || ts.toPath(sourceFile.fileName, currentDirectory, getCanonicalFileName);
                return sourceFile.version === hostCache.getVersion(path);
            }
            function programUpToDate() {
                // If we haven't create a program yet, then it is not up-to-date
                if (!program) {
                    return false;
                }
                // If number of files in the program do not match, it is not up-to-date
                var rootFileNames = hostCache.getRootFileNames();
                if (program.getSourceFiles().length !== rootFileNames.length) {
                    return false;
                }
                // If any file is not up-to-date, then the whole program is not up-to-date
                for (var _i = 0, rootFileNames_2 = rootFileNames; _i < rootFileNames_2.length; _i++) {
                    var fileName = rootFileNames_2[_i];
                    if (!sourceFileUpToDate(program.getSourceFile(fileName))) {
                        return false;
                    }
                }
                // If the compilation settings do no match, then the program is not up-to-date
                return ts.compareDataObjects(program.getCompilerOptions(), hostCache.compilationSettings());
            }
        }
        function getProgram() {
            synchronizeHostData();
            return program;
        }
        function cleanupSemanticCache() {
            // TODO: Should we jettison the program (or it's type checker) here?
        }
        function dispose() {
            if (program) {
                ts.forEach(program.getSourceFiles(), function (f) {
                    return documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions());
                });
            }
        }
        /// Diagnostics
        function getSyntacticDiagnostics(fileName) {
            synchronizeHostData();
            return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken);
        }
        /**
         * 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;
            }
            // 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 ts.concatenate(semanticDiagnostics, declarationDiagnostics);
        }
        function getCompilerOptionsDiagnostics() {
            synchronizeHostData();
            return program.getOptionsDiagnostics(cancellationToken).concat(program.getGlobalDiagnostics(cancellationToken));
        }
        /**
         * Get the name to be display in completion from a given symbol.
         *
         * @return undefined if the name is of external module otherwise a name with striped of any quote
         */
        function getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, location) {
            var displayName = ts.getDeclaredName(program.getTypeChecker(), symbol, location);
            if (displayName) {
                var firstCharCode = displayName.charCodeAt(0);
                // First check of the displayName is not external module; if it is an external module, it is not valid entry
                if ((symbol.flags & 1536 /* Namespace */) && (firstCharCode === 39 /* singleQuote */ || firstCharCode === 34 /* doubleQuote */)) {
                    // 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(displayName, target, performCharacterChecks);
        }
        /**
         * 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) {
            if (!name) {
                return undefined;
            }
            name = ts.stripQuotes(name);
            if (!name) {
                return undefined;
            }
            // 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) {
                if (!ts.isIdentifier(name, target)) {
                    return undefined;
                }
            }
            return name;
        }
        function getCompletionData(fileName, position) {
            var typeChecker = program.getTypeChecker();
            var sourceFile = getValidSourceFile(fileName);
            var isJavaScriptFile = ts.isSourceFileJavaScript(sourceFile);
            var isJsDocTagName = false;
            var start = new Date().getTime();
            var currentToken = ts.getTokenAtPosition(sourceFile, position);
            log("getCompletionData: Get current token: " + (new Date().getTime() - start));
            start = new Date().getTime();
            // Completion not allowed inside comments, bail out if this is the case
            var insideComment = isInsideComment(sourceFile, currentToken, position);
            log("getCompletionData: Is inside comment: " + (new Date().getTime() - start));
            if (insideComment) {
                // The current position is next to the '@' sign, when no tag name being provided yet.
                // Provide a full list of tag names
                if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64 /* at */) {
                    isJsDocTagName = true;
                }
                // Completion should work inside certain JsDoc tags. For example:
                //     /** @type {number | string} */
                // Completion should work in the brackets
                var insideJsDocTagExpression = false;
                var tag = ts.getJsDocTagAtPosition(sourceFile, position);
                if (tag) {
                    if (tag.tagName.pos <= position && position <= tag.tagName.end) {
                        isJsDocTagName = true;
                    }
                    switch (tag.kind) {
                        case 277 /* JSDocTypeTag */:
                        case 275 /* JSDocParameterTag */:
                        case 276 /* JSDocReturnTag */:
                            var tagWithExpression = tag;
                            if (tagWithExpression.typeExpression) {
                                insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end;
                            }
                            break;
                    }
                }
                if (isJsDocTagName) {
                    return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName };
                }
                if (!insideJsDocTagExpression) {
                    // 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 = new Date().getTime();
            var previousToken = ts.findPrecedingToken(position, sourceFile);
            log("getCompletionData: Get previous token 1: " + (new Date().getTime() - 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_5 = new Date().getTime();
                contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile);
                log("getCompletionData: Get previous token 2: " + (new Date().getTime() - start_5));
            }
            // 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);
            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_17 = contextToken.parent, kind = contextToken.kind;
                if (kind === 21 /* DotToken */) {
                    if (parent_17.kind === 172 /* PropertyAccessExpression */) {
                        node = contextToken.parent.expression;
                        isRightOfDot = true;
                    }
                    else if (parent_17.kind === 139 /* 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 */) {
                    if (kind === 25 /* LessThanToken */) {
                        isRightOfOpenTag = true;
                        location = contextToken;
                    }
                    else if (kind === 39 /* SlashToken */ && contextToken.parent.kind === 245 /* JsxClosingElement */) {
                        isStartingCloseTag = true;
                        location = contextToken;
                    }
                }
            }
            var semanticStart = new Date().getTime();
            var isMemberCompletion;
            var isNewIdentifierLocation;
            var symbols = [];
            if (isRightOfDot) {
                getTypeScriptMemberSymbols();
            }
            else if (isRightOfOpenTag) {
                var tagSymbols = typeChecker.getJsxIntrinsicTagNames();
                if (tryGetGlobalSymbols()) {
                    symbols = tagSymbols.concat(symbols.filter(function (s) { return !!(s.flags & (107455 /* Value */ | 8388608 /* 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: " + (new Date().getTime() - semanticStart));
            return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName };
            function getTypeScriptMemberSymbols() {
                // Right of dot member completion list
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
                if (node.kind === 69 /* Identifier */ || node.kind === 139 /* QualifiedName */ || node.kind === 172 /* PropertyAccessExpression */) {
                    var symbol = typeChecker.getSymbolAtLocation(node);
                    // This is an alias, follow what it aliases
                    if (symbol && symbol.flags & 8388608 /* Alias */) {
                        symbol = typeChecker.getAliasedSymbol(symbol);
                    }
                    if (symbol && symbol.flags & 1952 /* HasExports */) {
                        // Extract module or enum members
                        var exportedSymbols = typeChecker.getExportsOfModule(symbol);
                        ts.forEach(exportedSymbols, function (symbol) {
                            if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) {
                                symbols.push(symbol);
                            }
                        });
                    }
                }
                var type = typeChecker.getTypeAtLocation(node);
                addTypeProperties(type);
            }
            function addTypeProperties(type) {
                if (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 & 16384 /* 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 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 (jsxContainer = tryGetContainingJsxElement(contextToken)) {
                    var attrsType = void 0;
                    if ((jsxContainer.kind === 242 /* JsxSelfClosingElement */) || (jsxContainer.kind === 243 /* JsxOpeningElement */)) {
                        // Cursor is inside a JSX self-closing element or opening element
                        attrsType = typeChecker.getJsxElementAttributesType(jsxContainer);
                        if (attrsType) {
                            symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes);
                            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;
                /// TODO filter meaning based on the current context
                var symbolMeanings = 793056 /* Type */ | 107455 /* Value */ | 1536 /* Namespace */ | 8388608 /* Alias */;
                symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
                return true;
            }
            /**
             * 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 = new Date().getTime();
                var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) ||
                    isSolelyIdentifierDefinitionLocation(contextToken) ||
                    isDotOfNumericLiteral(contextToken) ||
                    isInJsxText(contextToken);
                log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start));
                return result;
            }
            function isInJsxText(contextToken) {
                if (contextToken.kind === 244 /* JsxText */) {
                    return true;
                }
                if (contextToken.kind === 27 /* GreaterThanToken */ && contextToken.parent) {
                    if (contextToken.parent.kind === 243 /* JsxOpeningElement */) {
                        return true;
                    }
                    if (contextToken.parent.kind === 245 /* JsxClosingElement */ || contextToken.parent.kind === 242 /* JsxSelfClosingElement */) {
                        return contextToken.parent.parent && contextToken.parent.parent.kind === 241 /* JsxElement */;
                    }
                }
                return false;
            }
            function isNewIdentifierDefinitionLocation(previousToken) {
                if (previousToken) {
                    var containingNodeKind = previousToken.parent.kind;
                    switch (previousToken.kind) {
                        case 24 /* CommaToken */:
                            return containingNodeKind === 174 /* CallExpression */ // func( a, |
                                || containingNodeKind === 148 /* Constructor */ // constructor( a, |   /* public, protected, private keywords are allowed here, so show completion */
                                || containingNodeKind === 175 /* NewExpression */ // new C(a, |
                                || containingNodeKind === 170 /* ArrayLiteralExpression */ // [a, |
                                || containingNodeKind === 187 /* BinaryExpression */ // const x = (a, |
                                || containingNodeKind === 156 /* FunctionType */; // var x: (s: string, list|
                        case 17 /* OpenParenToken */:
                            return containingNodeKind === 174 /* CallExpression */ // func( |
                                || containingNodeKind === 148 /* Constructor */ // constructor( |
                                || containingNodeKind === 175 /* NewExpression */ // new C(a|
                                || containingNodeKind === 178 /* ParenthesizedExpression */ // const x = (a|
                                || containingNodeKind === 164 /* ParenthesizedType */; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */
                        case 19 /* OpenBracketToken */:
                            return containingNodeKind === 170 /* ArrayLiteralExpression */ // [ |
                                || containingNodeKind === 153 /* IndexSignature */ // [ | : string ]
                                || containingNodeKind === 140 /* ComputedPropertyName */; // [ |    /* this can become an index signature */
                        case 125 /* ModuleKeyword */: // module |
                        case 126 /* NamespaceKeyword */:
                            return true;
                        case 21 /* DotToken */:
                            return containingNodeKind === 225 /* ModuleDeclaration */; // module A.|
                        case 15 /* OpenBraceToken */:
                            return containingNodeKind === 221 /* ClassDeclaration */; // class A{ |
                        case 56 /* EqualsToken */:
                            return containingNodeKind === 218 /* VariableDeclaration */ // const x = a|
                                || containingNodeKind === 187 /* BinaryExpression */; // x = a|
                        case 12 /* TemplateHead */:
                            return containingNodeKind === 189 /* TemplateExpression */; // `aa ${|
                        case 13 /* TemplateMiddle */:
                            return containingNodeKind === 197 /* TemplateSpan */; // `aa ${10} dd ${|
                        case 112 /* PublicKeyword */:
                        case 110 /* PrivateKeyword */:
                        case 111 /* ProtectedKeyword */:
                            return containingNodeKind === 145 /* 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 === 166 /* StringLiteralType */
                    || contextToken.kind === 10 /* RegularExpressionLiteral */
                    || ts.isTemplateLiteralKind(contextToken.kind)) {
                    var start_6 = 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_6 < position && position < end) {
                        return true;
                    }
                    if (position === end) {
                        return !!contextToken.isUnterminated
                            || contextToken.kind === 10 /* 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;
                var typeForObject;
                var existingMembers;
                if (objectLikeContainer.kind === 171 /* ObjectLiteralExpression */) {
                    // We are completing on contextual types, but may also include properties
                    // other than those within the declared type.
                    isNewIdentifierLocation = true;
                    typeForObject = typeChecker.getContextualType(objectLikeContainer);
                    existingMembers = objectLikeContainer.properties;
                }
                else if (objectLikeContainer.kind === 167 /* ObjectBindingPattern */) {
                    // We are *only* completing on properties from the type being destructured.
                    isNewIdentifierLocation = false;
                    var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent);
                    if (ts.isVariableLike(rootDeclaration)) {
                        // 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 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);
                        if (!canGetType && rootDeclaration.kind === 142 /* Parameter */) {
                            if (ts.isExpression(rootDeclaration.parent)) {
                                canGetType = !!typeChecker.getContextualType(rootDeclaration.parent);
                            }
                            else if (rootDeclaration.parent.kind === 147 /* MethodDeclaration */ || rootDeclaration.parent.kind === 150 /* SetAccessor */) {
                                canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent);
                            }
                        }
                        if (canGetType) {
                            typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
                            existingMembers = objectLikeContainer.elements;
                        }
                    }
                    else {
                        ts.Debug.fail("Root declaration is not variable-like.");
                    }
                }
                else {
                    ts.Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind);
                }
                if (!typeForObject) {
                    return false;
                }
                var typeMembers = typeChecker.getPropertiesOfType(typeForObject);
                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 === 233 /* NamedImports */ ?
                    230 /* ImportDeclaration */ :
                    236 /* ExportDeclaration */;
                var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind);
                var moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
                if (!moduleSpecifier) {
                    return false;
                }
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
                var exports;
                var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier);
                if (moduleSpecifierSymbol) {
                    exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol);
                }
                symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray;
                return true;
            }
            /**
             * 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 15 /* OpenBraceToken */: // const x = { |
                        case 24 /* CommaToken */:
                            var parent_18 = contextToken.parent;
                            if (parent_18 && (parent_18.kind === 171 /* ObjectLiteralExpression */ || parent_18.kind === 167 /* ObjectBindingPattern */)) {
                                return parent_18;
                            }
                            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 15 /* OpenBraceToken */: // import { |
                        case 24 /* CommaToken */:
                            switch (contextToken.parent.kind) {
                                case 233 /* NamedImports */:
                                case 237 /* NamedExports */:
                                    return contextToken.parent;
                            }
                    }
                }
                return undefined;
            }
            function tryGetContainingJsxElement(contextToken) {
                if (contextToken) {
                    var parent_19 = contextToken.parent;
                    switch (contextToken.kind) {
                        case 26 /* LessThanSlashToken */:
                        case 39 /* SlashToken */:
                        case 69 /* Identifier */:
                        case 246 /* JsxAttribute */:
                        case 247 /* JsxSpreadAttribute */:
                            if (parent_19 && (parent_19.kind === 242 /* JsxSelfClosingElement */ || parent_19.kind === 243 /* JsxOpeningElement */)) {
                                return parent_19;
                            }
                            else if (parent_19.kind === 246 /* JsxAttribute */) {
                                return parent_19.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_19 && ((parent_19.kind === 246 /* JsxAttribute */) || (parent_19.kind === 247 /* JsxSpreadAttribute */))) {
                                return parent_19.parent;
                            }
                            break;
                        case 16 /* CloseBraceToken */:
                            if (parent_19 &&
                                parent_19.kind === 248 /* JsxExpression */ &&
                                parent_19.parent &&
                                (parent_19.parent.kind === 246 /* JsxAttribute */)) {
                                return parent_19.parent.parent;
                            }
                            if (parent_19 && parent_19.kind === 247 /* JsxSpreadAttribute */) {
                                return parent_19.parent;
                            }
                            break;
                    }
                }
                return undefined;
            }
            function isFunction(kind) {
                switch (kind) {
                    case 179 /* FunctionExpression */:
                    case 180 /* ArrowFunction */:
                    case 220 /* FunctionDeclaration */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                    case 151 /* CallSignature */:
                    case 152 /* ConstructSignature */:
                    case 153 /* IndexSignature */:
                        return true;
                }
                return false;
            }
            /**
             * @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 24 /* CommaToken */:
                        return containingNodeKind === 218 /* VariableDeclaration */ ||
                            containingNodeKind === 219 /* VariableDeclarationList */ ||
                            containingNodeKind === 200 /* VariableStatement */ ||
                            containingNodeKind === 224 /* EnumDeclaration */ ||
                            isFunction(containingNodeKind) ||
                            containingNodeKind === 221 /* ClassDeclaration */ ||
                            containingNodeKind === 192 /* ClassExpression */ ||
                            containingNodeKind === 222 /* InterfaceDeclaration */ ||
                            containingNodeKind === 168 /* ArrayBindingPattern */ ||
                            containingNodeKind === 223 /* TypeAliasDeclaration */; // type Map, K, |
                    case 21 /* DotToken */:
                        return containingNodeKind === 168 /* ArrayBindingPattern */; // var [.|
                    case 54 /* ColonToken */:
                        return containingNodeKind === 169 /* BindingElement */; // var {x :html|
                    case 19 /* OpenBracketToken */:
                        return containingNodeKind === 168 /* ArrayBindingPattern */; // var [x|
                    case 17 /* OpenParenToken */:
                        return containingNodeKind === 252 /* CatchClause */ ||
                            isFunction(containingNodeKind);
                    case 15 /* OpenBraceToken */:
                        return containingNodeKind === 224 /* EnumDeclaration */ ||
                            containingNodeKind === 222 /* InterfaceDeclaration */ ||
                            containingNodeKind === 159 /* TypeLiteral */; // const x : { |
                    case 23 /* SemicolonToken */:
                        return containingNodeKind === 144 /* PropertySignature */ &&
                            contextToken.parent && contextToken.parent.parent &&
                            (contextToken.parent.parent.kind === 222 /* InterfaceDeclaration */ ||
                                contextToken.parent.parent.kind === 159 /* TypeLiteral */); // const x : { a; |
                    case 25 /* LessThanToken */:
                        return containingNodeKind === 221 /* ClassDeclaration */ ||
                            containingNodeKind === 192 /* ClassExpression */ ||
                            containingNodeKind === 222 /* InterfaceDeclaration */ ||
                            containingNodeKind === 223 /* TypeAliasDeclaration */ ||
                            isFunction(containingNodeKind);
                    case 113 /* StaticKeyword */:
                        return containingNodeKind === 145 /* PropertyDeclaration */;
                    case 22 /* DotDotDotToken */:
                        return containingNodeKind === 142 /* Parameter */ ||
                            (contextToken.parent && contextToken.parent.parent &&
                                contextToken.parent.parent.kind === 168 /* ArrayBindingPattern */); // var [...z|
                    case 112 /* PublicKeyword */:
                    case 110 /* PrivateKeyword */:
                    case 111 /* ProtectedKeyword */:
                        return containingNodeKind === 142 /* Parameter */;
                    case 116 /* AsKeyword */:
                        return containingNodeKind === 234 /* ImportSpecifier */ ||
                            containingNodeKind === 238 /* ExportSpecifier */ ||
                            containingNodeKind === 232 /* NamespaceImport */;
                    case 73 /* ClassKeyword */:
                    case 81 /* EnumKeyword */:
                    case 107 /* InterfaceKeyword */:
                    case 87 /* FunctionKeyword */:
                    case 102 /* VarKeyword */:
                    case 123 /* GetKeyword */:
                    case 131 /* SetKeyword */:
                    case 89 /* ImportKeyword */:
                    case 108 /* LetKeyword */:
                    case 74 /* ConstKeyword */:
                    case 114 /* YieldKeyword */:
                    case 134 /* TypeKeyword */:
                        return true;
                }
                // 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 false;
            }
            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 = {};
                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 (element.getStart() <= position && position <= element.getEnd()) {
                        continue;
                    }
                    var name_41 = element.propertyName || element.name;
                    existingImportsOrExports[name_41.text] = true;
                }
                if (ts.isEmpty(existingImportsOrExports)) {
                    return ts.filter(exportsOfModule, function (e) { return e.name !== "default"; });
                }
                return ts.filter(exportsOfModule, function (e) { return e.name !== "default" && !ts.lookUp(existingImportsOrExports, e.name); });
            }
            /**
             * 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 = {};
                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 !== 253 /* PropertyAssignment */ &&
                        m.kind !== 254 /* ShorthandPropertyAssignment */ &&
                        m.kind !== 169 /* BindingElement */ &&
                        m.kind !== 147 /* MethodDeclaration */) {
                        continue;
                    }
                    // If this is the current item we are editing right now, do not filter it out
                    if (m.getStart() <= position && position <= m.getEnd()) {
                        continue;
                    }
                    var existingName = void 0;
                    if (m.kind === 169 /* BindingElement */ && m.propertyName) {
                        // include only identifiers in completion list
                        if (m.propertyName.kind === 69 /* Identifier */) {
                            existingName = m.propertyName.text;
                        }
                    }
                    else {
                        // TODO(jfreeman): 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.
                        existingName = m.name.text;
                    }
                    existingMemberNames[existingName] = true;
                }
                return ts.filter(contextualMemberSymbols, function (m) { return !ts.lookUp(existingMemberNames, m.name); });
            }
            /**
             * 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 = {};
                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 (attr.getStart() <= position && position <= attr.getEnd()) {
                        continue;
                    }
                    if (attr.kind === 246 /* JsxAttribute */) {
                        seenNames[attr.name.text] = true;
                    }
                }
                return ts.filter(symbols, function (a) { return !ts.lookUp(seenNames, a.name); });
            }
        }
        function getCompletionsAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            if (ts.isInString(sourceFile, position)) {
                return getStringLiteralCompletionEntries(sourceFile, position);
            }
            var completionData = getCompletionData(fileName, position);
            if (!completionData) {
                return undefined;
            }
            var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isJsDocTagName = completionData.isJsDocTagName;
            if (isJsDocTagName) {
                // If the current position is a jsDoc tag name, only tag names should be provided for completion
                return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() };
            }
            var entries = [];
            if (ts.isSourceFileJavaScript(sourceFile)) {
                var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ false);
                ts.addRange(entries, getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames));
            }
            else {
                if (!symbols || symbols.length === 0) {
                    if (sourceFile.languageVariant === 1 /* JSX */ &&
                        location.parent && location.parent.kind === 245 /* 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;
                        entries.push({
                            name: tagName.text,
                            kind: undefined,
                            kindModifiers: undefined,
                            sortText: "0"
                        });
                    }
                    else {
                        return undefined;
                    }
                }
                getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true);
            }
            // Add keywords if this is not a member completion list
            if (!isMemberCompletion && !isJsDocTagName) {
                ts.addRange(entries, keywordCompletions);
            }
            return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries };
            function getJavaScriptCompletionEntries(sourceFile, position, uniqueNames) {
                var entries = [];
                var target = program.getCompilerOptions().target;
                var nameTable = getNameTable(sourceFile);
                for (var name_42 in nameTable) {
                    // Skip identifiers produced only from the current location
                    if (nameTable[name_42] === position) {
                        continue;
                    }
                    if (!uniqueNames[name_42]) {
                        uniqueNames[name_42] = name_42;
                        var displayName = getCompletionEntryDisplayName(ts.unescapeIdentifier(name_42), target, /*performCharacterChecks*/ true);
                        if (displayName) {
                            var entry = {
                                name: displayName,
                                kind: ScriptElementKind.warning,
                                kindModifiers: "",
                                sortText: "1"
                            };
                            entries.push(entry);
                        }
                    }
                }
                return entries;
            }
            function getAllJsDocCompletionEntries() {
                return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) {
                    return {
                        name: tagName,
                        kind: ScriptElementKind.keyword,
                        kindModifiers: "",
                        sortText: "0"
                    };
                }));
            }
            function createCompletionEntry(symbol, location, performCharacterChecks) {
                // 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, program.getCompilerOptions().target, performCharacterChecks, location);
                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: getSymbolKind(symbol, location),
                    kindModifiers: getSymbolModifiers(symbol),
                    sortText: "0"
                };
            }
            function getCompletionEntriesFromSymbols(symbols, entries, location, performCharacterChecks) {
                var start = new Date().getTime();
                var uniqueNames = {};
                if (symbols) {
                    for (var _i = 0, symbols_4 = symbols; _i < symbols_4.length; _i++) {
                        var symbol = symbols_4[_i];
                        var entry = createCompletionEntry(symbol, location, performCharacterChecks);
                        if (entry) {
                            var id = ts.escapeIdentifier(entry.name);
                            if (!ts.lookUp(uniqueNames, id)) {
                                entries.push(entry);
                                uniqueNames[id] = id;
                            }
                        }
                    }
                }
                log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
                return uniqueNames;
            }
            function getStringLiteralCompletionEntries(sourceFile, position) {
                var node = ts.findPrecedingToken(position, sourceFile);
                if (!node || node.kind !== 9 /* StringLiteral */) {
                    return undefined;
                }
                var argumentInfo = ts.SignatureHelp.getContainingArgumentInfo(node, position, sourceFile);
                if (argumentInfo) {
                    // Get string literal completions from specialized signatures of the target
                    return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo);
                }
                else if (ts.isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) {
                    // Get all names of properties on the expression
                    return getStringLiteralCompletionEntriesFromElementAccess(node.parent);
                }
                else {
                    // Otherwise, get the completions from the contextual type if one exists
                    return getStringLiteralCompletionEntriesFromContextualType(node);
                }
            }
            function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo) {
                var typeChecker = program.getTypeChecker();
                var candidates = [];
                var entries = [];
                typeChecker.getResolvedSignature(argumentInfo.invocation, candidates);
                for (var _i = 0, candidates_3 = candidates; _i < candidates_3.length; _i++) {
                    var candidate = candidates_3[_i];
                    if (candidate.parameters.length > argumentInfo.argumentIndex) {
                        var parameter = candidate.parameters[argumentInfo.argumentIndex];
                        addStringLiteralCompletionsFromType(typeChecker.getTypeAtLocation(parameter.valueDeclaration), entries);
                    }
                }
                if (entries.length) {
                    return { isMemberCompletion: false, isNewIdentifierLocation: true, entries: entries };
                }
                return undefined;
            }
            function getStringLiteralCompletionEntriesFromElementAccess(node) {
                var typeChecker = program.getTypeChecker();
                var type = typeChecker.getTypeAtLocation(node.expression);
                var entries = [];
                if (type) {
                    getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false);
                    if (entries.length) {
                        return { isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries };
                    }
                }
                return undefined;
            }
            function getStringLiteralCompletionEntriesFromContextualType(node) {
                var typeChecker = program.getTypeChecker();
                var type = typeChecker.getContextualType(node);
                if (type) {
                    var entries_2 = [];
                    addStringLiteralCompletionsFromType(type, entries_2);
                    if (entries_2.length) {
                        return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries_2 };
                    }
                }
                return undefined;
            }
            function addStringLiteralCompletionsFromType(type, result) {
                if (!type) {
                    return;
                }
                if (type.flags & 16384 /* Union */) {
                    ts.forEach(type.types, function (t) { return addStringLiteralCompletionsFromType(t, result); });
                }
                else {
                    if (type.flags & 256 /* StringLiteral */) {
                        result.push({
                            name: type.text,
                            kindModifiers: ScriptElementKindModifier.none,
                            kind: ScriptElementKind.variableElement,
                            sortText: "0"
                        });
                    }
                }
            }
        }
        function getCompletionEntryDetails(fileName, position, entryName) {
            synchronizeHostData();
            // Compute all the completion symbols again.
            var completionData = getCompletionData(fileName, position);
            if (completionData) {
                var symbols = completionData.symbols, location_2 = completionData.location;
                // Find the symbol with the matching entry name.
                var target_2 = program.getCompilerOptions().target;
                // 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.forEach(symbols, function (s) { return getCompletionEntryDisplayNameForSymbol(s, target_2, /*performCharacterChecks*/ false, location_2) === entryName ? s : undefined; });
                if (symbol) {
                    var _a = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location_2, location_2, 7 /* All */), displayParts = _a.displayParts, documentation = _a.documentation, symbolKind = _a.symbolKind;
                    return {
                        name: entryName,
                        kindModifiers: getSymbolModifiers(symbol),
                        kind: symbolKind,
                        displayParts: displayParts,
                        documentation: documentation
                    };
                }
            }
            // Didn't find a symbol with this name.  See if we can find a keyword instead.
            var keywordCompletion = ts.forEach(keywordCompletions, function (c) { return c.name === entryName; });
            if (keywordCompletion) {
                return {
                    name: entryName,
                    kind: ScriptElementKind.keyword,
                    kindModifiers: ScriptElementKindModifier.none,
                    displayParts: [ts.displayPart(entryName, SymbolDisplayPartKind.keyword)],
                    documentation: undefined
                };
            }
            return undefined;
        }
        // TODO(drosen): use contextual SemanticMeaning.
        function getSymbolKind(symbol, location) {
            var flags = symbol.getFlags();
            if (flags & 32 /* Class */)
                return ts.getDeclarationOfKind(symbol, 192 /* ClassExpression */) ?
                    ScriptElementKind.localClassElement : ScriptElementKind.classElement;
            if (flags & 384 /* Enum */)
                return ScriptElementKind.enumElement;
            if (flags & 524288 /* TypeAlias */)
                return ScriptElementKind.typeElement;
            if (flags & 64 /* Interface */)
                return ScriptElementKind.interfaceElement;
            if (flags & 262144 /* TypeParameter */)
                return ScriptElementKind.typeParameterElement;
            var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location);
            if (result === ScriptElementKind.unknown) {
                if (flags & 262144 /* TypeParameter */)
                    return ScriptElementKind.typeParameterElement;
                if (flags & 8 /* EnumMember */)
                    return ScriptElementKind.variableElement;
                if (flags & 8388608 /* Alias */)
                    return ScriptElementKind.alias;
                if (flags & 1536 /* Module */)
                    return ScriptElementKind.moduleElement;
            }
            return result;
        }
        function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, location) {
            var typeChecker = program.getTypeChecker();
            if (typeChecker.isUndefinedSymbol(symbol)) {
                return ScriptElementKind.variableElement;
            }
            if (typeChecker.isArgumentsSymbol(symbol)) {
                return ScriptElementKind.localVariableElement;
            }
            if (location.kind === 97 /* ThisKeyword */ && ts.isExpression(location)) {
                return ScriptElementKind.parameterElement;
            }
            if (flags & 3 /* Variable */) {
                if (ts.isFirstDeclarationOfSymbolParameter(symbol)) {
                    return ScriptElementKind.parameterElement;
                }
                else if (symbol.valueDeclaration && ts.isConst(symbol.valueDeclaration)) {
                    return ScriptElementKind.constElement;
                }
                else if (ts.forEach(symbol.declarations, ts.isLet)) {
                    return ScriptElementKind.letElement;
                }
                return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement;
            }
            if (flags & 16 /* Function */)
                return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement;
            if (flags & 32768 /* GetAccessor */)
                return ScriptElementKind.memberGetAccessorElement;
            if (flags & 65536 /* SetAccessor */)
                return ScriptElementKind.memberSetAccessorElement;
            if (flags & 8192 /* Method */)
                return ScriptElementKind.memberFunctionElement;
            if (flags & 16384 /* Constructor */)
                return ScriptElementKind.constructorImplementationElement;
            if (flags & 4 /* Property */) {
                if (flags & 268435456 /* SyntheticProperty */) {
                    // 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 ScriptElementKind.memberVariableElement;
                        }
                        ts.Debug.assert(!!(rootSymbolFlags & 8192 /* Method */));
                    });
                    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 ScriptElementKind.memberFunctionElement;
                        }
                        return ScriptElementKind.memberVariableElement;
                    }
                    return unionPropertyKind;
                }
                return ScriptElementKind.memberVariableElement;
            }
            return ScriptElementKind.unknown;
        }
        function getSymbolModifiers(symbol) {
            return symbol && symbol.declarations && symbol.declarations.length > 0
                ? ts.getNodeModifiers(symbol.declarations[0])
                : ScriptElementKindModifier.none;
        }
        // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location
        function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, enclosingDeclaration, location, semanticMeaning) {
            if (semanticMeaning === void 0) { semanticMeaning = getMeaningFromLocation(location); }
            var typeChecker = program.getTypeChecker();
            var displayParts = [];
            var documentation;
            var symbolFlags = symbol.flags;
            var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location);
            var hasAddedSymbolInfo;
            var isThisExpression = location.kind === 97 /* ThisKeyword */ && ts.isExpression(location);
            var type;
            // Class at constructor site need to be shown as constructor apart from property,method, vars
            if (symbolKind !== ScriptElementKind.unknown || symbolFlags & 32 /* Class */ || symbolFlags & 8388608 /* Alias */) {
                // If it is accessor they are allowed only if location is at name of the accessor
                if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
                    symbolKind = ScriptElementKind.memberVariableElement;
                }
                var signature = void 0;
                type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol, location);
                if (type) {
                    if (location.parent && location.parent.kind === 172 /* 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 callExpression = void 0;
                    if (location.kind === 174 /* CallExpression */ || location.kind === 175 /* NewExpression */) {
                        callExpression = location;
                    }
                    else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
                        callExpression = location.parent;
                    }
                    if (callExpression) {
                        var candidateSignatures = [];
                        signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures);
                        if (!signature && candidateSignatures.length) {
                            // Use the first candidate:
                            signature = candidateSignatures[0];
                        }
                        var useConstructSignatures = callExpression.kind === 175 /* NewExpression */ || callExpression.expression.kind === 95 /* 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 = ScriptElementKind.constructorImplementationElement;
                                addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                            }
                            else if (symbolFlags & 8388608 /* Alias */) {
                                symbolKind = ScriptElementKind.alias;
                                pushTypePart(symbolKind);
                                displayParts.push(ts.spacePart());
                                if (useConstructSignatures) {
                                    displayParts.push(ts.keywordPart(92 /* NewKeyword */));
                                    displayParts.push(ts.spacePart());
                                }
                                addFullSymbolName(symbol);
                            }
                            else {
                                addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                            }
                            switch (symbolKind) {
                                case ScriptElementKind.memberVariableElement:
                                case ScriptElementKind.variableElement:
                                case ScriptElementKind.constElement:
                                case ScriptElementKind.letElement:
                                case ScriptElementKind.parameterElement:
                                case ScriptElementKind.localVariableElement:
                                    // If it is call or construct signature of lambda's write type name
                                    displayParts.push(ts.punctuationPart(54 /* ColonToken */));
                                    displayParts.push(ts.spacePart());
                                    if (useConstructSignatures) {
                                        displayParts.push(ts.keywordPart(92 /* NewKeyword */));
                                        displayParts.push(ts.spacePart());
                                    }
                                    if (!(type.flags & 65536 /* Anonymous */) && type.symbol) {
                                        ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */));
                                    }
                                    addSignatureDisplayParts(signature, allSignatures, 8 /* WriteArrowStyleSignature */);
                                    break;
                                default:
                                    // Just signature
                                    addSignatureDisplayParts(signature, allSignatures);
                            }
                            hasAddedSymbolInfo = true;
                        }
                    }
                    else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & 98304 /* Accessor */)) ||
                        (location.kind === 121 /* ConstructorKeyword */ && location.parent.kind === 148 /* Constructor */)) {
                        // get the signature from the declaration and write it
                        var functionDeclaration = location.parent;
                        var allSignatures = functionDeclaration.kind === 148 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
                        if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
                            signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
                        }
                        else {
                            signature = allSignatures[0];
                        }
                        if (functionDeclaration.kind === 148 /* Constructor */) {
                            // show (constructor) Type(...) signature
                            symbolKind = ScriptElementKind.constructorImplementationElement;
                            addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                        }
                        else {
                            // (function/method) symbol(..signature)
                            addPrefixForAnyFunctionOrVar(functionDeclaration.kind === 151 /* 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, 192 /* 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(ScriptElementKind.localClassElement);
                }
                else {
                    // Class declaration has name which is not local.
                    displayParts.push(ts.keywordPart(73 /* ClassKeyword */));
                }
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.keywordPart(107 /* InterfaceKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
            }
            if (symbolFlags & 524288 /* TypeAlias */) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.keywordPart(134 /* TypeKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                writeTypeParametersOfSymbol(symbol, sourceFile);
                displayParts.push(ts.spacePart());
                displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                displayParts.push(ts.spacePart());
                ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration));
            }
            if (symbolFlags & 384 /* Enum */) {
                addNewLineIfDisplayPartsExist();
                if (ts.forEach(symbol.declarations, ts.isConstEnumDeclaration)) {
                    displayParts.push(ts.keywordPart(74 /* ConstKeyword */));
                    displayParts.push(ts.spacePart());
                }
                displayParts.push(ts.keywordPart(81 /* EnumKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if (symbolFlags & 1536 /* Module */) {
                addNewLineIfDisplayPartsExist();
                var declaration = ts.getDeclarationOfKind(symbol, 225 /* ModuleDeclaration */);
                var isNamespace = declaration && declaration.name && declaration.name.kind === 69 /* Identifier */;
                displayParts.push(ts.keywordPart(isNamespace ? 126 /* NamespaceKeyword */ : 125 /* ModuleKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
            }
            if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                displayParts.push(ts.textPart("type parameter"));
                displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                displayParts.push(ts.spacePart());
                displayParts.push(ts.keywordPart(90 /* InKeyword */));
                displayParts.push(ts.spacePart());
                if (symbol.parent) {
                    // Class/Interface type parameter
                    addFullSymbolName(symbol.parent, enclosingDeclaration);
                    writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
                }
                else {
                    // Method/function type parameter
                    var declaration = ts.getDeclarationOfKind(symbol, 141 /* TypeParameter */);
                    ts.Debug.assert(declaration !== undefined);
                    declaration = declaration.parent;
                    if (declaration) {
                        if (ts.isFunctionLikeKind(declaration.kind)) {
                            var signature = typeChecker.getSignatureFromDeclaration(declaration);
                            if (declaration.kind === 152 /* ConstructSignature */) {
                                displayParts.push(ts.keywordPart(92 /* NewKeyword */));
                                displayParts.push(ts.spacePart());
                            }
                            else if (declaration.kind !== 151 /* CallSignature */ && declaration.name) {
                                addFullSymbolName(declaration.symbol);
                            }
                            ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */));
                        }
                        else {
                            // Type alias type parameter
                            // For example
                            //      type list<T> = T[];  // Both T will go through same code path
                            displayParts.push(ts.keywordPart(134 /* TypeKeyword */));
                            displayParts.push(ts.spacePart());
                            addFullSymbolName(declaration.symbol);
                            writeTypeParametersOfSymbol(declaration.symbol, sourceFile);
                        }
                    }
                }
            }
            if (symbolFlags & 8 /* EnumMember */) {
                addPrefixForAnyFunctionOrVar(symbol, "enum member");
                var declaration = symbol.declarations[0];
                if (declaration.kind === 255 /* EnumMember */) {
                    var constantValue = typeChecker.getConstantValue(declaration);
                    if (constantValue !== undefined) {
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                        displayParts.push(ts.spacePart());
                        displayParts.push(ts.displayPart(constantValue.toString(), SymbolDisplayPartKind.numericLiteral));
                    }
                }
            }
            if (symbolFlags & 8388608 /* Alias */) {
                addNewLineIfDisplayPartsExist();
                displayParts.push(ts.keywordPart(89 /* ImportKeyword */));
                displayParts.push(ts.spacePart());
                addFullSymbolName(symbol);
                ts.forEach(symbol.declarations, function (declaration) {
                    if (declaration.kind === 229 /* ImportEqualsDeclaration */) {
                        var importEqualsDeclaration = declaration;
                        if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) {
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                            displayParts.push(ts.spacePart());
                            displayParts.push(ts.keywordPart(129 /* RequireKeyword */));
                            displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                            displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), SymbolDisplayPartKind.stringLiteral));
                            displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                        }
                        else {
                            var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference);
                            if (internalAliasSymbol) {
                                displayParts.push(ts.spacePart());
                                displayParts.push(ts.operatorPart(56 /* EqualsToken */));
                                displayParts.push(ts.spacePart());
                                addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
                            }
                        }
                        return true;
                    }
                });
            }
            if (!hasAddedSymbolInfo) {
                if (symbolKind !== ScriptElementKind.unknown) {
                    if (type) {
                        if (isThisExpression) {
                            addNewLineIfDisplayPartsExist();
                            displayParts.push(ts.keywordPart(97 /* ThisKeyword */));
                        }
                        else {
                            addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                        }
                        // For properties, variables and local vars: show the type
                        if (symbolKind === ScriptElementKind.memberVariableElement ||
                            symbolFlags & 3 /* Variable */ ||
                            symbolKind === ScriptElementKind.localVariableElement ||
                            isThisExpression) {
                            displayParts.push(ts.punctuationPart(54 /* 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 === ScriptElementKind.memberFunctionElement) {
                            var allSignatures = type.getNonNullableType().getCallSignatures();
                            addSignatureDisplayParts(allSignatures[0], allSignatures);
                        }
                    }
                }
                else {
                    symbolKind = getSymbolKind(symbol, location);
                }
            }
            if (!documentation) {
                documentation = symbol.getDocumentationComment();
            }
            return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind };
            function addNewLineIfDisplayPartsExist() {
                if (displayParts.length) {
                    displayParts.push(ts.lineBreakPart());
                }
            }
            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 ScriptElementKind.variableElement:
                    case ScriptElementKind.functionElement:
                    case ScriptElementKind.letElement:
                    case ScriptElementKind.constElement:
                    case ScriptElementKind.constructorImplementationElement:
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        return;
                    default:
                        displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                        displayParts.push(ts.textOrKeywordPart(symbolKind));
                        displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                        return;
                }
            }
            function addSignatureDisplayParts(signature, allSignatures, flags) {
                ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 32 /* WriteTypeArgumentsOfSignature */));
                if (allSignatures.length > 1) {
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.punctuationPart(17 /* OpenParenToken */));
                    displayParts.push(ts.operatorPart(35 /* PlusToken */));
                    displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), SymbolDisplayPartKind.numericLiteral));
                    displayParts.push(ts.spacePart());
                    displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads"));
                    displayParts.push(ts.punctuationPart(18 /* CloseParenToken */));
                }
                documentation = signature.getDocumentationComment();
            }
            function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
                var typeParameterParts = ts.mapToDisplayParts(function (writer) {
                    typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
                });
                ts.addRange(displayParts, typeParameterParts);
            }
        }
        function getQuickInfoAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            if (isLabelName(node)) {
                return undefined;
            }
            var typeChecker = program.getTypeChecker();
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
                // Try getting just type at this position and show
                switch (node.kind) {
                    case 69 /* Identifier */:
                    case 172 /* PropertyAccessExpression */:
                    case 139 /* QualifiedName */:
                    case 97 /* ThisKeyword */:
                    case 165 /* ThisType */:
                    case 95 /* SuperKeyword */:
                        // For the identifiers/this/super etc get the type at position
                        var type = typeChecker.getTypeAtLocation(node);
                        if (type) {
                            return {
                                kind: ScriptElementKind.unknown,
                                kindModifiers: ScriptElementKindModifier.none,
                                textSpan: ts.createTextSpan(node.getStart(), node.getWidth()),
                                displayParts: ts.typeToDisplayParts(typeChecker, type, getContainerNode(node)),
                                documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined
                            };
                        }
                }
                return undefined;
            }
            var displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), node);
            return {
                kind: displayPartsDocumentationsAndKind.symbolKind,
                kindModifiers: getSymbolModifiers(symbol),
                textSpan: ts.createTextSpan(node.getStart(), node.getWidth()),
                displayParts: displayPartsDocumentationsAndKind.displayParts,
                documentation: displayPartsDocumentationsAndKind.documentation
            };
        }
        function createDefinitionInfo(node, symbolKind, symbolName, containerName) {
            return {
                fileName: node.getSourceFile().fileName,
                textSpan: ts.createTextSpanFromBounds(node.getStart(), node.getEnd()),
                kind: symbolKind,
                name: symbolName,
                containerKind: undefined,
                containerName: containerName
            };
        }
        function getDefinitionFromSymbol(symbol, node) {
            var typeChecker = program.getTypeChecker();
            var result = [];
            var declarations = symbol.getDeclarations();
            var symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
            var symbolKind = getSymbolKind(symbol, node);
            var containerSymbol = symbol.parent;
            var containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : "";
            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 (isNewExpressionTarget(location) || location.kind === 121 /* 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 (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
                    return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
                }
                return false;
            }
            function tryAddSignature(signatureDeclarations, selectConstructors, symbolKind, symbolName, containerName, result) {
                var declarations = [];
                var definition;
                ts.forEach(signatureDeclarations, function (d) {
                    if ((selectConstructors && d.kind === 148 /* Constructor */) ||
                        (!selectConstructors && (d.kind === 220 /* FunctionDeclaration */ || d.kind === 147 /* MethodDeclaration */ || d.kind === 146 /* MethodSignature */))) {
                        declarations.push(d);
                        if (d.body)
                            definition = d;
                    }
                });
                if (definition) {
                    result.push(createDefinitionInfo(definition, symbolKind, symbolName, containerName));
                    return true;
                }
                else if (declarations.length) {
                    result.push(createDefinitionInfo(ts.lastOrUndefined(declarations), symbolKind, symbolName, containerName));
                    return true;
                }
                return false;
            }
        }
        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: ScriptElementKind.scriptElement,
                name: name,
                containerName: undefined,
                containerKind: undefined
            };
        }
        /// Goto definition
        function getDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            /// 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)];
                }
                return undefined;
            }
            // Type reference directives
            var typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
            if (typeReferenceDirective) {
                var referenceFile = ts.lookUp(program.getResolvedTypeReferenceDirectives(), typeReferenceDirective.fileName);
                if (referenceFile && referenceFile.resolvedFileName) {
                    return [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)];
                }
                return undefined;
            }
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            // Labels
            if (isJumpStatementTarget(node)) {
                var labelName = node.text;
                var label = getTargetLabel(node.parent, node.text);
                return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
            }
            var typeChecker = program.getTypeChecker();
            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 & 8388608 /* Alias */) {
                var declaration = symbol.declarations[0];
                // 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 a named import.
                //
                if (node.kind === 69 /* Identifier */ &&
                    (node.parent === declaration ||
                        (declaration.kind === 234 /* ImportSpecifier */ && declaration.parent && declaration.parent.kind === 233 /* NamedImports */))) {
                    symbol = typeChecker.getAliasedSymbol(symbol);
                }
            }
            // 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 === 254 /* ShorthandPropertyAssignment */) {
                var shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
                if (!shorthandSymbol) {
                    return [];
                }
                var shorthandDeclarations = shorthandSymbol.getDeclarations();
                var shorthandSymbolKind_1 = getSymbolKind(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); });
            }
            return getDefinitionFromSymbol(symbol, node);
        }
        /// Goto type
        function getTypeDefinitionAtPosition(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position);
            if (node === sourceFile) {
                return undefined;
            }
            var typeChecker = program.getTypeChecker();
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol) {
                return undefined;
            }
            var type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
            if (!type) {
                return undefined;
            }
            if (type.flags & 16384 /* Union */) {
                var result_3 = [];
                ts.forEach(type.types, function (t) {
                    if (t.symbol) {
                        ts.addRange(/*to*/ result_3, /*from*/ getDefinitionFromSymbol(t.symbol, node));
                    }
                });
                return result_3;
            }
            if (!type.symbol) {
                return undefined;
            }
            return getDefinitionFromSymbol(type.symbol, node);
        }
        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);
            var node = ts.getTouchingWord(sourceFile, position);
            if (!node) {
                return undefined;
            }
            return getSemanticDocumentHighlights(node) || getSyntacticDocumentHighlights(node);
            function getHighlightSpanForNode(node) {
                var start = node.getStart();
                var end = node.getEnd();
                return {
                    fileName: sourceFile.fileName,
                    textSpan: ts.createTextSpanFromBounds(start, end),
                    kind: HighlightSpanKind.none
                };
            }
            function getSemanticDocumentHighlights(node) {
                if (node.kind === 69 /* Identifier */ ||
                    node.kind === 97 /* ThisKeyword */ ||
                    node.kind === 165 /* ThisType */ ||
                    node.kind === 95 /* SuperKeyword */ ||
                    node.kind === 9 /* StringLiteral */ ||
                    isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
                    var referencedSymbols = getReferencedSymbolsForNode(node, sourceFilesToSearch, /*findInStrings*/ false, /*findInComments*/ false);
                    return convertReferencedSymbols(referencedSymbols);
                }
                return undefined;
                function convertReferencedSymbols(referencedSymbols) {
                    if (!referencedSymbols) {
                        return undefined;
                    }
                    var fileNameToDocumentHighlights = {};
                    var result = [];
                    for (var _i = 0, referencedSymbols_1 = referencedSymbols; _i < referencedSymbols_1.length; _i++) {
                        var referencedSymbol = referencedSymbols_1[_i];
                        for (var _a = 0, _b = referencedSymbol.references; _a < _b.length; _a++) {
                            var referenceEntry = _b[_a];
                            var fileName_1 = referenceEntry.fileName;
                            var documentHighlights = ts.getProperty(fileNameToDocumentHighlights, fileName_1);
                            if (!documentHighlights) {
                                documentHighlights = { fileName: fileName_1, highlightSpans: [] };
                                fileNameToDocumentHighlights[fileName_1] = documentHighlights;
                                result.push(documentHighlights);
                            }
                            documentHighlights.highlightSpans.push({
                                textSpan: referenceEntry.textSpan,
                                kind: referenceEntry.isWriteAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference
                            });
                        }
                    }
                    return result;
                }
            }
            function getSyntacticDocumentHighlights(node) {
                var fileName = sourceFile.fileName;
                var highlightSpans = getHighlightSpans(node);
                if (!highlightSpans || highlightSpans.length === 0) {
                    return undefined;
                }
                return [{ fileName: 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) {
                    if (node) {
                        switch (node.kind) {
                            case 88 /* IfKeyword */:
                            case 80 /* ElseKeyword */:
                                if (hasKind(node.parent, 203 /* IfStatement */)) {
                                    return getIfElseOccurrences(node.parent);
                                }
                                break;
                            case 94 /* ReturnKeyword */:
                                if (hasKind(node.parent, 211 /* ReturnStatement */)) {
                                    return getReturnOccurrences(node.parent);
                                }
                                break;
                            case 98 /* ThrowKeyword */:
                                if (hasKind(node.parent, 215 /* ThrowStatement */)) {
                                    return getThrowOccurrences(node.parent);
                                }
                                break;
                            case 72 /* CatchKeyword */:
                                if (hasKind(parent(parent(node)), 216 /* TryStatement */)) {
                                    return getTryCatchFinallyOccurrences(node.parent.parent);
                                }
                                break;
                            case 100 /* TryKeyword */:
                            case 85 /* FinallyKeyword */:
                                if (hasKind(parent(node), 216 /* TryStatement */)) {
                                    return getTryCatchFinallyOccurrences(node.parent);
                                }
                                break;
                            case 96 /* SwitchKeyword */:
                                if (hasKind(node.parent, 213 /* SwitchStatement */)) {
                                    return getSwitchCaseDefaultOccurrences(node.parent);
                                }
                                break;
                            case 71 /* CaseKeyword */:
                            case 77 /* DefaultKeyword */:
                                if (hasKind(parent(parent(parent(node))), 213 /* SwitchStatement */)) {
                                    return getSwitchCaseDefaultOccurrences(node.parent.parent.parent);
                                }
                                break;
                            case 70 /* BreakKeyword */:
                            case 75 /* ContinueKeyword */:
                                if (hasKind(node.parent, 210 /* BreakStatement */) || hasKind(node.parent, 209 /* ContinueStatement */)) {
                                    return getBreakOrContinueStatementOccurrences(node.parent);
                                }
                                break;
                            case 86 /* ForKeyword */:
                                if (hasKind(node.parent, 206 /* ForStatement */) ||
                                    hasKind(node.parent, 207 /* ForInStatement */) ||
                                    hasKind(node.parent, 208 /* ForOfStatement */)) {
                                    return getLoopBreakContinueOccurrences(node.parent);
                                }
                                break;
                            case 104 /* WhileKeyword */:
                            case 79 /* DoKeyword */:
                                if (hasKind(node.parent, 205 /* WhileStatement */) || hasKind(node.parent, 204 /* DoStatement */)) {
                                    return getLoopBreakContinueOccurrences(node.parent);
                                }
                                break;
                            case 121 /* ConstructorKeyword */:
                                if (hasKind(node.parent, 148 /* Constructor */)) {
                                    return getConstructorOccurrences(node.parent);
                                }
                                break;
                            case 123 /* GetKeyword */:
                            case 131 /* SetKeyword */:
                                if (hasKind(node.parent, 149 /* GetAccessor */) || hasKind(node.parent, 150 /* SetAccessor */)) {
                                    return getGetAndSetOccurrences(node.parent);
                                }
                                break;
                            default:
                                if (ts.isModifierKind(node.kind) && node.parent &&
                                    (ts.isDeclaration(node.parent) || node.parent.kind === 200 /* VariableStatement */)) {
                                    return getModifierOccurrences(node.kind, node.parent);
                                }
                        }
                    }
                    return undefined;
                }
                /**
                 * 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 === 215 /* ThrowStatement */) {
                            statementAccumulator.push(node);
                        }
                        else if (node.kind === 216 /* 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_20 = child.parent;
                        if (ts.isFunctionBlock(parent_20) || parent_20.kind === 256 /* SourceFile */) {
                            return parent_20;
                        }
                        // 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_20.kind === 216 /* TryStatement */) {
                            var tryStatement = parent_20;
                            if (tryStatement.tryBlock === child && tryStatement.catchClause) {
                                return child;
                            }
                        }
                        child = parent_20;
                    }
                    return undefined;
                }
                function aggregateAllBreakAndContinueStatements(node) {
                    var statementAccumulator = [];
                    aggregate(node);
                    return statementAccumulator;
                    function aggregate(node) {
                        if (node.kind === 210 /* BreakStatement */ || node.kind === 209 /* 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_1 = statement.parent; node_1; node_1 = node_1.parent) {
                        switch (node_1.kind) {
                            case 213 /* SwitchStatement */:
                                if (statement.kind === 209 /* ContinueStatement */) {
                                    continue;
                                }
                            // Fall through.
                            case 206 /* ForStatement */:
                            case 207 /* ForInStatement */:
                            case 208 /* ForOfStatement */:
                            case 205 /* WhileStatement */:
                            case 204 /* DoStatement */:
                                if (!statement.label || isLabeledBy(node_1, statement.label.text)) {
                                    return node_1;
                                }
                                break;
                            default:
                                // Don't cross function boundaries.
                                if (ts.isFunctionLike(node_1)) {
                                    return undefined;
                                }
                                break;
                        }
                    }
                    return undefined;
                }
                function getModifierOccurrences(modifier, declaration) {
                    var container = declaration.parent;
                    // Make sure we only highlight the keyword when it makes sense to do so.
                    if (ts.isAccessibilityModifier(modifier)) {
                        if (!(container.kind === 221 /* ClassDeclaration */ ||
                            container.kind === 192 /* ClassExpression */ ||
                            (declaration.kind === 142 /* Parameter */ && hasKind(container, 148 /* Constructor */)))) {
                            return undefined;
                        }
                    }
                    else if (modifier === 113 /* StaticKeyword */) {
                        if (!(container.kind === 221 /* ClassDeclaration */ || container.kind === 192 /* ClassExpression */)) {
                            return undefined;
                        }
                    }
                    else if (modifier === 82 /* ExportKeyword */ || modifier === 122 /* DeclareKeyword */) {
                        if (!(container.kind === 226 /* ModuleBlock */ || container.kind === 256 /* SourceFile */)) {
                            return undefined;
                        }
                    }
                    else if (modifier === 115 /* AbstractKeyword */) {
                        if (!(container.kind === 221 /* ClassDeclaration */ || declaration.kind === 221 /* ClassDeclaration */)) {
                            return undefined;
                        }
                    }
                    else {
                        // unsupported modifier
                        return undefined;
                    }
                    var keywords = [];
                    var modifierFlag = getFlagFromModifier(modifier);
                    var nodes;
                    switch (container.kind) {
                        case 226 /* ModuleBlock */:
                        case 256 /* SourceFile */:
                            // Container is either a class declaration or the declaration is a classDeclaration
                            if (modifierFlag & 128 /* Abstract */) {
                                nodes = declaration.members.concat(declaration);
                            }
                            else {
                                nodes = container.statements;
                            }
                            break;
                        case 148 /* Constructor */:
                            nodes = container.parameters.concat(container.parent.members);
                            break;
                        case 221 /* ClassDeclaration */:
                        case 192 /* ClassExpression */:
                            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.forEach(container.members, function (member) {
                                    return member.kind === 148 /* Constructor */ && member;
                                });
                                if (constructor) {
                                    nodes = nodes.concat(constructor.parameters);
                                }
                            }
                            else if (modifierFlag & 128 /* Abstract */) {
                                nodes = nodes.concat(container);
                            }
                            break;
                        default:
                            ts.Debug.fail("Invalid container kind.");
                    }
                    ts.forEach(nodes, function (node) {
                        if (node.modifiers && node.flags & modifierFlag) {
                            ts.forEach(node.modifiers, function (child) { return pushKeywordIf(keywords, child, modifier); });
                        }
                    });
                    return ts.map(keywords, getHighlightSpanForNode);
                    function getFlagFromModifier(modifier) {
                        switch (modifier) {
                            case 112 /* PublicKeyword */:
                                return 4 /* Public */;
                            case 110 /* PrivateKeyword */:
                                return 8 /* Private */;
                            case 111 /* ProtectedKeyword */:
                                return 16 /* Protected */;
                            case 113 /* StaticKeyword */:
                                return 32 /* Static */;
                            case 82 /* ExportKeyword */:
                                return 1 /* Export */;
                            case 122 /* DeclareKeyword */:
                                return 2 /* Ambient */;
                            case 115 /* AbstractKeyword */:
                                return 128 /* Abstract */;
                            default:
                                ts.Debug.fail();
                        }
                    }
                }
                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, 149 /* GetAccessor */);
                    tryPushAccessorKeyword(accessorDeclaration.symbol, 150 /* SetAccessor */);
                    return ts.map(keywords, getHighlightSpanForNode);
                    function tryPushAccessorKeyword(accessorSymbol, accessorKind) {
                        var accessor = ts.getDeclarationOfKind(accessorSymbol, accessorKind);
                        if (accessor) {
                            ts.forEach(accessor.getChildren(), function (child) { return pushKeywordIf(keywords, child, 123 /* GetKeyword */, 131 /* 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, 121 /* ConstructorKeyword */);
                        });
                    });
                    return ts.map(keywords, getHighlightSpanForNode);
                }
                function getLoopBreakContinueOccurrences(loopNode) {
                    var keywords = [];
                    if (pushKeywordIf(keywords, loopNode.getFirstToken(), 86 /* ForKeyword */, 104 /* WhileKeyword */, 79 /* DoKeyword */)) {
                        // If we succeeded and got a do-while loop, then start looking for a 'while' keyword.
                        if (loopNode.kind === 204 /* DoStatement */) {
                            var loopTokens = loopNode.getChildren();
                            for (var i = loopTokens.length - 1; i >= 0; i--) {
                                if (pushKeywordIf(keywords, loopTokens[i], 104 /* WhileKeyword */)) {
                                    break;
                                }
                            }
                        }
                    }
                    var breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement);
                    ts.forEach(breaksAndContinues, function (statement) {
                        if (ownsBreakOrContinueStatement(loopNode, statement)) {
                            pushKeywordIf(keywords, statement.getFirstToken(), 70 /* BreakKeyword */, 75 /* ContinueKeyword */);
                        }
                    });
                    return ts.map(keywords, getHighlightSpanForNode);
                }
                function getBreakOrContinueStatementOccurrences(breakOrContinueStatement) {
                    var owner = getBreakOrContinueOwner(breakOrContinueStatement);
                    if (owner) {
                        switch (owner.kind) {
                            case 206 /* ForStatement */:
                            case 207 /* ForInStatement */:
                            case 208 /* ForOfStatement */:
                            case 204 /* DoStatement */:
                            case 205 /* WhileStatement */:
                                return getLoopBreakContinueOccurrences(owner);
                            case 213 /* SwitchStatement */:
                                return getSwitchCaseDefaultOccurrences(owner);
                        }
                    }
                    return undefined;
                }
                function getSwitchCaseDefaultOccurrences(switchStatement) {
                    var keywords = [];
                    pushKeywordIf(keywords, switchStatement.getFirstToken(), 96 /* 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(), 71 /* CaseKeyword */, 77 /* DefaultKeyword */);
                        var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause);
                        ts.forEach(breaksAndContinues, function (statement) {
                            if (ownsBreakOrContinueStatement(switchStatement, statement)) {
                                pushKeywordIf(keywords, statement.getFirstToken(), 70 /* BreakKeyword */);
                            }
                        });
                    });
                    return ts.map(keywords, getHighlightSpanForNode);
                }
                function getTryCatchFinallyOccurrences(tryStatement) {
                    var keywords = [];
                    pushKeywordIf(keywords, tryStatement.getFirstToken(), 100 /* TryKeyword */);
                    if (tryStatement.catchClause) {
                        pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), 72 /* CatchKeyword */);
                    }
                    if (tryStatement.finallyBlock) {
                        var finallyKeyword = ts.findChildOfKind(tryStatement, 85 /* FinallyKeyword */, sourceFile);
                        pushKeywordIf(keywords, finallyKeyword, 85 /* FinallyKeyword */);
                    }
                    return ts.map(keywords, getHighlightSpanForNode);
                }
                function getThrowOccurrences(throwStatement) {
                    var owner = getThrowStatementOwner(throwStatement);
                    if (!owner) {
                        return undefined;
                    }
                    var keywords = [];
                    ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) {
                        pushKeywordIf(keywords, throwStatement.getFirstToken(), 98 /* 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(), 94 /* ReturnKeyword */);
                        });
                    }
                    return ts.map(keywords, getHighlightSpanForNode);
                }
                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, 199 /* Block */))) {
                        return undefined;
                    }
                    var keywords = [];
                    ts.forEachReturnStatement(func.body, function (returnStatement) {
                        pushKeywordIf(keywords, returnStatement.getFirstToken(), 94 /* ReturnKeyword */);
                    });
                    // Include 'throw' statements that do not occur within a try block.
                    ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) {
                        pushKeywordIf(keywords, throwStatement.getFirstToken(), 98 /* ThrowKeyword */);
                    });
                    return ts.map(keywords, getHighlightSpanForNode);
                }
                function getIfElseOccurrences(ifStatement) {
                    var keywords = [];
                    // Traverse upwards through all parent if-statements linked by their else-branches.
                    while (hasKind(ifStatement.parent, 203 /* 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], 88 /* 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], 80 /* ElseKeyword */)) {
                                break;
                            }
                        }
                        if (!hasKind(ifStatement.elseStatement, 203 /* 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 === 80 /* 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: fileName,
                                    textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end),
                                    kind: HighlightSpanKind.reference
                                });
                                i++; // skip the next keyword
                                continue;
                            }
                        }
                        // Ordinary case: just highlight the keyword.
                        result.push(getHighlightSpanForNode(keywords[i]));
                    }
                    return result;
                }
            }
        }
        /// References and Occurrences
        function getOccurrencesAtPositionCore(fileName, position) {
            synchronizeHostData();
            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 === HighlightSpanKind.writtenReference,
                            isDefinition: false
                        });
                    }
                }
                return result;
            }
        }
        function convertReferences(referenceSymbols) {
            if (!referenceSymbols) {
                return undefined;
            }
            var referenceEntries = [];
            for (var _i = 0, referenceSymbols_1 = referenceSymbols; _i < referenceSymbols_1.length; _i++) {
                var referenceSymbol = referenceSymbols_1[_i];
                ts.addRange(referenceEntries, referenceSymbol.references);
            }
            return referenceEntries;
        }
        function findRenameLocations(fileName, position, findInStrings, findInComments) {
            var referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments);
            return convertReferences(referencedSymbols);
        }
        function getReferencesAtPosition(fileName, position) {
            var referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false);
            return convertReferences(referencedSymbols);
        }
        function findReferences(fileName, position) {
            var referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false);
            // Only include referenced symbols that have a valid definition.
            return ts.filter(referencedSymbols, function (rs) { return !!rs.definition; });
        }
        function findReferencedSymbols(fileName, position, findInStrings, findInComments) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
            if (node === sourceFile) {
                return undefined;
            }
            switch (node.kind) {
                case 8 /* NumericLiteral */:
                    if (!isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
                        break;
                    }
                // Fallthrough
                case 69 /* Identifier */:
                case 97 /* ThisKeyword */:
                // case SyntaxKind.SuperKeyword: TODO:GH#9268
                case 9 /* StringLiteral */:
                    return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments);
            }
            return undefined;
        }
        function isThis(node) {
            switch (node.kind) {
                case 97 /* ThisKeyword */:
                    // case SyntaxKind.ThisType: TODO: GH#9267
                    return true;
                case 69 /* Identifier */:
                    // 'this' as a parameter
                    return node.originalKeywordKind === 97 /* ThisKeyword */ && node.parent.kind === 142 /* Parameter */;
                default:
                    return false;
            }
        }
        function getReferencedSymbolsForNode(node, sourceFiles, findInStrings, findInComments) {
            var typeChecker = program.getTypeChecker();
            // Labels
            if (isLabelName(node)) {
                if (isJumpStatementTarget(node)) {
                    var labelDefinition = 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) : undefined;
                }
                else {
                    // it is a label definition and not a target, search within the parent labeledStatement
                    return getLabelReferencesInNode(node.parent, node);
                }
            }
            if (isThis(node)) {
                return getReferencesForThisKeyword(node, sourceFiles);
            }
            if (node.kind === 95 /* SuperKeyword */) {
                return getReferencesForSuperKeyword(node);
            }
            var symbol = typeChecker.getSymbolAtLocation(node);
            if (!symbol && node.kind === 9 /* StringLiteral */) {
                return getReferencesForStringLiteral(node, sourceFiles);
            }
            // Could not find a symbol e.g. unknown identifier
            if (!symbol) {
                // Can't have references to something that we have no symbol for.
                return undefined;
            }
            var declarations = symbol.declarations;
            // The symbol was an internal symbol and does not have a declaration e.g. undefined symbol
            if (!declarations || !declarations.length) {
                return undefined;
            }
            var result;
            // Compute the meaning from the location and the symbol it references
            var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations);
            // Get the text to search for.
            // Note: if this is an external module symbol, the name doesn't include quotes.
            var declaredName = ts.stripQuotes(ts.getDeclaredName(typeChecker, symbol, node));
            // 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);
            // Maps from a symbol ID to the ReferencedSymbol entry in 'result'.
            var symbolToIndex = [];
            if (scope) {
                result = [];
                getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex);
            }
            else {
                var internedName = getInternedName(symbol, node, declarations);
                for (var _i = 0, sourceFiles_4 = sourceFiles; _i < sourceFiles_4.length; _i++) {
                    var sourceFile = sourceFiles_4[_i];
                    cancellationToken.throwIfCancellationRequested();
                    var nameTable = getNameTable(sourceFile);
                    if (ts.lookUp(nameTable, internedName) !== undefined) {
                        result = result || [];
                        getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex);
                    }
                }
            }
            return result;
            function getDefinition(symbol) {
                var info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node);
                var name = ts.map(info.displayParts, function (p) { return p.text; }).join("");
                var declarations = symbol.declarations;
                if (!declarations || declarations.length === 0) {
                    return undefined;
                }
                return {
                    containerKind: "",
                    containerName: "",
                    name: name,
                    kind: info.symbolKind,
                    fileName: declarations[0].getSourceFile().fileName,
                    textSpan: ts.createTextSpan(declarations[0].getStart(), 0)
                };
            }
            function getAliasSymbolForPropertyNameSymbol(symbol, location) {
                if (symbol.flags & 8388608 /* Alias */) {
                    // Default import get alias
                    var defaultImport = ts.getDeclarationOfKind(symbol, 231 /* ImportClause */);
                    if (defaultImport) {
                        return typeChecker.getAliasedSymbol(symbol);
                    }
                    var importOrExportSpecifier = ts.forEach(symbol.declarations, function (declaration) { return (declaration.kind === 234 /* ImportSpecifier */ ||
                        declaration.kind === 238 /* ExportSpecifier */) ? declaration : undefined; });
                    if (importOrExportSpecifier &&
                        // export { a }
                        (!importOrExportSpecifier.propertyName ||
                            // export {a as class } where a is location
                            importOrExportSpecifier.propertyName === location)) {
                        // If Import specifier -> get alias
                        // else Export specifier -> get local target
                        return importOrExportSpecifier.kind === 234 /* ImportSpecifier */ ?
                            typeChecker.getAliasedSymbol(symbol) :
                            typeChecker.getExportSpecifierLocalTargetSymbol(importOrExportSpecifier);
                    }
                }
                return undefined;
            }
            function getPropertySymbolOfDestructuringAssignment(location) {
                return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) &&
                    typeChecker.getPropertySymbolOfDestructuringAssignment(location);
            }
            function isObjectBindingPatternElementWithoutPropertyName(symbol) {
                var bindingElement = ts.getDeclarationOfKind(symbol, 169 /* BindingElement */);
                return bindingElement &&
                    bindingElement.parent.kind === 167 /* ObjectBindingPattern */ &&
                    !bindingElement.propertyName;
            }
            function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol) {
                if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
                    var bindingElement = ts.getDeclarationOfKind(symbol, 169 /* BindingElement */);
                    var typeOfPattern = typeChecker.getTypeAtLocation(bindingElement.parent);
                    return typeOfPattern && typeChecker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
                }
                return undefined;
            }
            function getInternedName(symbol, location, declarations) {
                // 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 under the cursor.
                if (ts.isImportOrExportSpecifierName(location)) {
                    return location.getText();
                }
                // 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);
                symbol = localExportDefaultSymbol || symbol;
                return ts.stripQuotes(symbol.name);
            }
            /**
             * 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 valueDeclaration = symbol.valueDeclaration;
                if (valueDeclaration && (valueDeclaration.kind === 179 /* FunctionExpression */ || valueDeclaration.kind === 192 /* ClassExpression */)) {
                    return valueDeclaration;
                }
                // If this is private property or method, the scope is the containing class
                if (symbol.flags & (4 /* Property */ | 8192 /* Method */)) {
                    var privateDeclaration = ts.forEach(symbol.getDeclarations(), function (d) { return (d.flags & 8 /* Private */) ? d : undefined; });
                    if (privateDeclaration) {
                        return ts.getAncestor(privateDeclaration, 221 /* ClassDeclaration */);
                    }
                }
                // If the symbol is an import we would like to find it if we are looking for what it imports.
                // So consider it visible outside its declaration scope.
                if (symbol.flags & 8388608 /* Alias */) {
                    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 (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
                    return undefined;
                }
                // if this symbol is visible from its parent container, e.g. exported, then bail out
                // if symbol correspond to the union property - bail out
                if (symbol.parent || (symbol.flags & 268435456 /* SyntheticProperty */)) {
                    return undefined;
                }
                var scope;
                var declarations = symbol.getDeclarations();
                if (declarations) {
                    for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) {
                        var declaration = declarations_9[_i];
                        var container = getContainerNode(declaration);
                        if (!container) {
                            return undefined;
                        }
                        if (scope && scope !== container) {
                            // Different declarations have different containers, bail out
                            return undefined;
                        }
                        if (container.kind === 256 /* SourceFile */ && !ts.isExternalModule(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;
                    }
                }
                return scope;
            }
            function getPossibleSymbolReferencePositions(sourceFile, symbolName, start, end) {
                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, start);
                while (position >= 0) {
                    cancellationToken.throwIfCancellationRequested();
                    // If we are past the end, stop looking
                    if (position > 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), 2 /* Latest */)) &&
                        (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 2 /* 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.getStart(), container.getEnd());
                ts.forEach(possiblePositions, function (position) {
                    cancellationToken.throwIfCancellationRequested();
                    var node = ts.getTouchingWord(sourceFile, position);
                    if (!node || node.getWidth() !== labelName.length) {
                        return;
                    }
                    // Only pick labels that are either the target label, or have a target that is the target label
                    if (node === targetLabel ||
                        (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) {
                        references.push(getReferenceEntryFromNode(node));
                    }
                });
                var definition = {
                    containerKind: "",
                    containerName: "",
                    fileName: targetLabel.getSourceFile().fileName,
                    kind: ScriptElementKind.label,
                    name: labelName,
                    textSpan: ts.createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd())
                };
                return [{ definition: definition, references: references }];
            }
            function isValidReferencePosition(node, searchSymbolName) {
                if (node) {
                    // Compare the length so we filter out strict superstrings of the symbol we are looking for
                    switch (node.kind) {
                        case 69 /* Identifier */:
                            return node.getWidth() === searchSymbolName.length;
                        case 9 /* StringLiteral */:
                            if (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
                                isNameOfExternalModuleImportOrDeclaration(node)) {
                                // For string literals we have two additional chars for the quotes
                                return node.getWidth() === searchSymbolName.length + 2;
                            }
                            break;
                        case 8 /* NumericLiteral */:
                            if (isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
                                return node.getWidth() === searchSymbolName.length;
                            }
                            break;
                    }
                }
                return false;
            }
            /** 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 getReferencesInNode(container, searchSymbol, searchText, searchLocation, searchMeaning, findInStrings, findInComments, result, symbolToIndex) {
                var sourceFile = container.getSourceFile();
                var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
                var start = findInComments ? container.getFullStart() : container.getStart();
                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, start, container.getEnd());
                if (possiblePositions.length) {
                    // Build the set of symbols to search for, initially it has only the current symbol
                    var searchSymbols_1 = populateSearchSymbolSet(searchSymbol, searchLocation);
                    ts.forEach(possiblePositions, function (position) {
                        cancellationToken.throwIfCancellationRequested();
                        var referenceLocation = ts.getTouchingPropertyName(sourceFile, position);
                        if (!isValidReferencePosition(referenceLocation, searchText)) {
                            // 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 ((findInStrings && ts.isInString(sourceFile, position)) ||
                                (findInComments && 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.
                                result.push({
                                    definition: undefined,
                                    references: [{
                                            fileName: sourceFile.fileName,
                                            textSpan: ts.createTextSpan(position, searchText.length),
                                            isWriteAccess: false,
                                            isDefinition: false
                                        }]
                                });
                            }
                            return;
                        }
                        if (!(getMeaningFromLocation(referenceLocation) & searchMeaning)) {
                            return;
                        }
                        var referenceSymbol = typeChecker.getSymbolAtLocation(referenceLocation);
                        if (referenceSymbol) {
                            var referenceSymbolDeclaration = referenceSymbol.valueDeclaration;
                            var shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration);
                            var relatedSymbol = getRelatedSymbol(searchSymbols_1, referenceSymbol, referenceLocation);
                            if (relatedSymbol) {
                                var referencedSymbol = getReferencedSymbol(relatedSymbol);
                                referencedSymbol.references.push(getReferenceEntryFromNode(referenceLocation));
                            }
                            else if (!(referenceSymbol.flags & 67108864 /* Transient */) && searchSymbols_1.indexOf(shorthandValueSymbol) >= 0) {
                                var referencedSymbol = getReferencedSymbol(shorthandValueSymbol);
                                referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name));
                            }
                        }
                    });
                }
                return;
                function getReferencedSymbol(symbol) {
                    var symbolId = ts.getSymbolId(symbol);
                    var index = symbolToIndex[symbolId];
                    if (index === undefined) {
                        index = result.length;
                        symbolToIndex[symbolId] = index;
                        result.push({
                            definition: getDefinition(symbol),
                            references: []
                        });
                    }
                    return result[index];
                }
                function isInNonReferenceComment(sourceFile, position) {
                    return ts.isInCommentHelper(sourceFile, position, isNonReferenceComment);
                    function isNonReferenceComment(c) {
                        var commentText = sourceFile.text.substring(c.pos, c.end);
                        return !tripleSlashDirectivePrefixRegex.test(commentText);
                    }
                }
            }
            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 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                    case 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                    case 148 /* Constructor */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        staticFlag &= searchSpaceNode.flags;
                        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.getStart(), searchSpaceNode.getEnd());
                ts.forEach(possiblePositions, function (position) {
                    cancellationToken.throwIfCancellationRequested();
                    var node = ts.getTouchingWord(sourceFile, position);
                    if (!node || node.kind !== 95 /* SuperKeyword */) {
                        return;
                    }
                    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 */ & container.flags) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) {
                        references.push(getReferenceEntryFromNode(node));
                    }
                });
                var definition = getDefinition(searchSpaceNode.symbol);
                return [{ definition: definition, references: references }];
            }
            function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles) {
                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 147 /* MethodDeclaration */:
                    case 146 /* MethodSignature */:
                        if (ts.isObjectLiteralMethod(searchSpaceNode)) {
                            break;
                        }
                    // fall through
                    case 145 /* PropertyDeclaration */:
                    case 144 /* PropertySignature */:
                    case 148 /* Constructor */:
                    case 149 /* GetAccessor */:
                    case 150 /* SetAccessor */:
                        staticFlag &= searchSpaceNode.flags;
                        searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
                        break;
                    case 256 /* SourceFile */:
                        if (ts.isExternalModule(searchSpaceNode)) {
                            return undefined;
                        }
                    // Fall through
                    case 220 /* FunctionDeclaration */:
                    case 179 /* 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 === 256 /* SourceFile */) {
                    ts.forEach(sourceFiles, function (sourceFile) {
                        possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd());
                        getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references);
                    });
                }
                else {
                    var sourceFile = searchSpaceNode.getSourceFile();
                    possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd());
                    getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references);
                }
                return [{
                        definition: {
                            containerKind: "",
                            containerName: "",
                            fileName: node.getSourceFile().fileName,
                            kind: ScriptElementKind.variableElement,
                            name: "this",
                            textSpan: ts.createTextSpanFromBounds(node.getStart(), node.getEnd())
                        },
                        references: references
                    }];
                function getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result) {
                    ts.forEach(possiblePositions, function (position) {
                        cancellationToken.throwIfCancellationRequested();
                        var node = ts.getTouchingWord(sourceFile, position);
                        if (!node || !isThis(node)) {
                            return;
                        }
                        var container = ts.getThisContainer(node, /* includeArrowFunctions */ false);
                        switch (searchSpaceNode.kind) {
                            case 179 /* FunctionExpression */:
                            case 220 /* FunctionDeclaration */:
                                if (searchSpaceNode.symbol === container.symbol) {
                                    result.push(getReferenceEntryFromNode(node));
                                }
                                break;
                            case 147 /* MethodDeclaration */:
                            case 146 /* MethodSignature */:
                                if (ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) {
                                    result.push(getReferenceEntryFromNode(node));
                                }
                                break;
                            case 192 /* ClassExpression */:
                            case 221 /* 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 && (container.flags & 32 /* Static */) === staticFlag) {
                                    result.push(getReferenceEntryFromNode(node));
                                }
                                break;
                            case 256 /* SourceFile */:
                                if (container.kind === 256 /* SourceFile */ && !ts.isExternalModule(container)) {
                                    result.push(getReferenceEntryFromNode(node));
                                }
                                break;
                        }
                    });
                }
            }
            function getReferencesForStringLiteral(node, sourceFiles) {
                var typeChecker = program.getTypeChecker();
                var type = getStringLiteralTypeForNode(node, typeChecker);
                if (!type) {
                    // nothing to do here. moving on
                    return undefined;
                }
                var references = [];
                for (var _i = 0, sourceFiles_5 = sourceFiles; _i < sourceFiles_5.length; _i++) {
                    var sourceFile = sourceFiles_5[_i];
                    var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, type.text, sourceFile.getStart(), sourceFile.getEnd());
                    getReferencesForStringLiteralInFile(sourceFile, type, possiblePositions, references);
                }
                return [{
                        definition: {
                            containerKind: "",
                            containerName: "",
                            fileName: node.getSourceFile().fileName,
                            kind: ScriptElementKind.variableElement,
                            name: type.text,
                            textSpan: ts.createTextSpanFromBounds(node.getStart(), node.getEnd())
                        },
                        references: references
                    }];
                function getReferencesForStringLiteralInFile(sourceFile, searchType, possiblePositions, references) {
                    for (var _i = 0, possiblePositions_1 = possiblePositions; _i < possiblePositions_1.length; _i++) {
                        var position = possiblePositions_1[_i];
                        cancellationToken.throwIfCancellationRequested();
                        var node_2 = ts.getTouchingWord(sourceFile, position);
                        if (!node_2 || node_2.kind !== 9 /* StringLiteral */) {
                            return;
                        }
                        var type_1 = getStringLiteralTypeForNode(node_2, typeChecker);
                        if (type_1 === searchType) {
                            references.push(getReferenceEntryFromNode(node_2));
                        }
                    }
                }
            }
            function populateSearchSymbolSet(symbol, location) {
                // The search set contains at least the current symbol
                var result = [symbol];
                // If the location is name of property symbol from object literal destructuring pattern
                // Search the property symbol
                //      for ( { property: p2 } of elems) { }
                var containingObjectLiteralElement = getContainingObjectLiteralElement(location);
                if (containingObjectLiteralElement && containingObjectLiteralElement.kind !== 254 /* ShorthandPropertyAssignment */) {
                    var propertySymbol = getPropertySymbolOfDestructuringAssignment(location);
                    if (propertySymbol) {
                        result.push(propertySymbol);
                    }
                }
                // If the symbol is an alias, add what it aliases to the list
                //     import {a} from "mod";
                //     export {a}
                // If the symbol is an alias to default declaration, add what it aliases to the list
                //     declare "mod" { export default class B { } }
                //     import B from "mod";
                //// For export specifiers, the exported name can be referring to a local symbol, e.g.:
                ////     import {a} from "mod";
                ////     export {a as somethingElse}
                //// We want the *local* declaration of 'a' as declared in the import,
                //// *not* as declared within "mod" (or farther)
                var aliasSymbol = getAliasSymbolForPropertyNameSymbol(symbol, location);
                if (aliasSymbol) {
                    result = result.concat(populateSearchSymbolSet(aliasSymbol, location));
                }
                // 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
                if (containingObjectLiteralElement) {
                    ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement), function (contextualSymbol) {
                        ts.addRange(result, typeChecker.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 = typeChecker.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 === 142 /* Parameter */ &&
                    ts.isParameterPropertyDeclaration(symbol.valueDeclaration)) {
                    result = result.concat(typeChecker.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);
                if (bindingElementPropertySymbol) {
                    result.push(bindingElementPropertySymbol);
                }
                // 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
                ts.forEach(typeChecker.getRootSymbols(symbol), function (rootSymbol) {
                    if (rootSymbol !== symbol) {
                        result.push(rootSymbol);
                    }
                    // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
                    if (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
                        getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ {});
                    }
                });
                return result;
            }
            /**
             * 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) {
                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 (ts.hasProperty(previousIterationSymbolsCache, symbol.name)) {
                    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 === 222 /* InterfaceDeclaration */) {
                            ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), getPropertySymbolFromTypeReference);
                        }
                    });
                }
                return;
                function getPropertySymbolFromTypeReference(typeReference) {
                    if (typeReference) {
                        var type = typeChecker.getTypeAtLocation(typeReference);
                        if (type) {
                            var propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
                            if (propertySymbol) {
                                result.push.apply(result, typeChecker.getRootSymbols(propertySymbol));
                            }
                            // Visit the typeReference as well to see if it directly or indirectly use that property
                            previousIterationSymbolsCache[symbol.name] = symbol;
                            getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache);
                        }
                    }
                }
            }
            function getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation) {
                if (searchSymbols.indexOf(referenceSymbol) >= 0) {
                    return referenceSymbol;
                }
                // If the reference symbol is an alias, check if what it is aliasing is one of the search
                // symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness.
                var aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation);
                if (aliasSymbol) {
                    return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation);
                }
                // 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 = getContainingObjectLiteralElement(referenceLocation);
                if (containingObjectLiteralElement) {
                    var contextualSymbol = ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement), function (contextualSymbol) {
                        return ts.forEach(typeChecker.getRootSymbols(contextualSymbol), function (s) { return searchSymbols.indexOf(s) >= 0 ? s : undefined; });
                    });
                    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);
                    if (propertySymbol && searchSymbols.indexOf(propertySymbol) >= 0) {
                        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);
                if (bindingElementPropertySymbol && searchSymbols.indexOf(bindingElementPropertySymbol) >= 0) {
                    return bindingElementPropertySymbol;
                }
                // 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(typeChecker.getRootSymbols(referenceSymbol), function (rootSymbol) {
                    // if it is in the list, then we are done
                    if (searchSymbols.indexOf(rootSymbol) >= 0) {
                        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 (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
                        var result_4 = [];
                        getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result_4, /*previousIterationSymbolsCache*/ {});
                        return ts.forEach(result_4, function (s) { return searchSymbols.indexOf(s) >= 0 ? s : undefined; });
                    }
                    return undefined;
                });
            }
            function getNameFromObjectLiteralElement(node) {
                if (node.name.kind === 140 /* 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.kind)) {
                        return nameExpression.text;
                    }
                    return undefined;
                }
                return node.name.text;
            }
            function getPropertySymbolsFromContextualType(node) {
                var objectLiteral = node.parent;
                var contextualType = typeChecker.getContextualType(objectLiteral);
                var name = getNameFromObjectLiteralElement(node);
                if (name && contextualType) {
                    var result_5 = [];
                    var symbol_1 = contextualType.getProperty(name);
                    if (symbol_1) {
                        result_5.push(symbol_1);
                    }
                    if (contextualType.flags & 16384 /* Union */) {
                        ts.forEach(contextualType.types, function (t) {
                            var symbol = t.getProperty(name);
                            if (symbol) {
                                result_5.push(symbol);
                            }
                        });
                    }
                    return result_5;
                }
                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 = getMeaningFromDeclaration(declaration);
                            if (declarationMeaning & meaning) {
                                meaning |= declarationMeaning;
                            }
                        }
                    } while (meaning !== lastIterationMeaning);
                }
                return meaning;
            }
        }
        function getReferenceEntryFromNode(node) {
            var start = node.getStart();
            var end = node.getEnd();
            if (node.kind === 9 /* StringLiteral */) {
                start += 1;
                end -= 1;
            }
            return {
                fileName: node.getSourceFile().fileName,
                textSpan: ts.createTextSpanFromBounds(start, end),
                isWriteAccess: isWriteAccess(node),
                isDefinition: ts.isDeclarationName(node) || ts.isLiteralComputedPropertyDeclarationName(node)
            };
        }
        /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
        function isWriteAccess(node) {
            if (node.kind === 69 /* Identifier */ && ts.isDeclarationName(node)) {
                return true;
            }
            var parent = node.parent;
            if (parent) {
                if (parent.kind === 186 /* PostfixUnaryExpression */ || parent.kind === 185 /* PrefixUnaryExpression */) {
                    return true;
                }
                else if (parent.kind === 187 /* BinaryExpression */ && parent.left === node) {
                    var operator = parent.operatorToken.kind;
                    return 56 /* FirstAssignment */ <= operator && operator <= 68 /* LastAssignment */;
                }
            }
            return false;
        }
        /// NavigateTo
        function getNavigateToItems(searchValue, maxResultCount) {
            synchronizeHostData();
            var checker = getProgram().getTypeChecker();
            return ts.NavigateTo.getNavigateToItems(program, checker, cancellationToken, searchValue, maxResultCount);
        }
        function getEmitOutput(fileName) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var outputFiles = [];
            function writeFile(fileName, data, writeByteOrderMark) {
                outputFiles.push({
                    name: fileName,
                    writeByteOrderMark: writeByteOrderMark,
                    text: data
                });
            }
            var emitOutput = program.emit(sourceFile, writeFile, cancellationToken);
            return {
                outputFiles: outputFiles,
                emitSkipped: emitOutput.emitSkipped
            };
        }
        function getMeaningFromDeclaration(node) {
            switch (node.kind) {
                case 142 /* Parameter */:
                case 218 /* VariableDeclaration */:
                case 169 /* BindingElement */:
                case 145 /* PropertyDeclaration */:
                case 144 /* PropertySignature */:
                case 253 /* PropertyAssignment */:
                case 254 /* ShorthandPropertyAssignment */:
                case 255 /* EnumMember */:
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                case 148 /* Constructor */:
                case 149 /* GetAccessor */:
                case 150 /* SetAccessor */:
                case 220 /* FunctionDeclaration */:
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                case 252 /* CatchClause */:
                    return 1 /* Value */;
                case 141 /* TypeParameter */:
                case 222 /* InterfaceDeclaration */:
                case 223 /* TypeAliasDeclaration */:
                case 159 /* TypeLiteral */:
                    return 2 /* Type */;
                case 221 /* ClassDeclaration */:
                case 224 /* EnumDeclaration */:
                    return 1 /* Value */ | 2 /* Type */;
                case 225 /* 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 233 /* NamedImports */:
                case 234 /* ImportSpecifier */:
                case 229 /* ImportEqualsDeclaration */:
                case 230 /* ImportDeclaration */:
                case 235 /* ExportAssignment */:
                case 236 /* ExportDeclaration */:
                    return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
                // An external module can be a Value
                case 256 /* SourceFile */:
                    return 4 /* Namespace */ | 1 /* Value */;
            }
            return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
        }
        function isTypeReference(node) {
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) {
                node = node.parent;
            }
            return node.parent.kind === 155 /* TypeReference */ ||
                (node.parent.kind === 194 /* ExpressionWithTypeArguments */ && !ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent)) ||
                (node.kind === 97 /* ThisKeyword */ && !ts.isExpression(node)) ||
                node.kind === 165 /* ThisType */;
        }
        function isNamespaceReference(node) {
            return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node);
        }
        function isPropertyAccessNamespaceReference(node) {
            var root = node;
            var isLastClause = true;
            if (root.parent.kind === 172 /* PropertyAccessExpression */) {
                while (root.parent && root.parent.kind === 172 /* PropertyAccessExpression */) {
                    root = root.parent;
                }
                isLastClause = root.name === node;
            }
            if (!isLastClause && root.parent.kind === 194 /* ExpressionWithTypeArguments */ && root.parent.parent.kind === 251 /* HeritageClause */) {
                var decl = root.parent.parent.parent;
                return (decl.kind === 221 /* ClassDeclaration */ && root.parent.parent.token === 106 /* ImplementsKeyword */) ||
                    (decl.kind === 222 /* InterfaceDeclaration */ && root.parent.parent.token === 83 /* ExtendsKeyword */);
            }
            return false;
        }
        function isQualifiedNameNamespaceReference(node) {
            var root = node;
            var isLastClause = true;
            if (root.parent.kind === 139 /* QualifiedName */) {
                while (root.parent && root.parent.kind === 139 /* QualifiedName */) {
                    root = root.parent;
                }
                isLastClause = root.right === node;
            }
            return root.parent.kind === 155 /* TypeReference */ && !isLastClause;
        }
        function isInRightSideOfImport(node) {
            while (node.parent.kind === 139 /* QualifiedName */) {
                node = node.parent;
            }
            return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node;
        }
        function getMeaningFromRightHandSideOfImportEquals(node) {
            ts.Debug.assert(node.kind === 69 /* Identifier */);
            //     import a = |b|; // Namespace
            //     import a = |b.c|; // Value, type, namespace
            //     import a = |b.c|.d; // Namespace
            if (node.parent.kind === 139 /* QualifiedName */ &&
                node.parent.right === node &&
                node.parent.parent.kind === 229 /* ImportEqualsDeclaration */) {
                return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
            }
            return 4 /* Namespace */;
        }
        function getMeaningFromLocation(node) {
            if (node.parent.kind === 235 /* ExportAssignment */) {
                return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
            }
            else if (isInRightSideOfImport(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 {
                return 1 /* Value */;
            }
        }
        // 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 getNameOrDottedNameSpan(fileName, startPos, endPos) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // Get node at the location
            var node = ts.getTouchingPropertyName(sourceFile, startPos);
            if (node === sourceFile) {
                return;
            }
            switch (node.kind) {
                case 172 /* PropertyAccessExpression */:
                case 139 /* QualifiedName */:
                case 9 /* StringLiteral */:
                case 166 /* StringLiteralType */:
                case 84 /* FalseKeyword */:
                case 99 /* TrueKeyword */:
                case 93 /* NullKeyword */:
                case 95 /* SuperKeyword */:
                case 97 /* ThisKeyword */:
                case 165 /* ThisType */:
                case 69 /* Identifier */:
                    break;
                // Cant create the text span
                default:
                    return;
            }
            var nodeForStartPos = node;
            while (true) {
                if (isRightSideOfPropertyAccess(nodeForStartPos) || 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 (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 === 225 /* 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) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.NavigationBar.getNavigationBarItems(sourceFile);
        }
        function getSemanticClassifications(fileName, span) {
            return convertClassifications(getEncodedSemanticClassifications(fileName, span));
        }
        function checkForClassificationCancellation(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 225 /* ModuleDeclaration */:
                case 221 /* ClassDeclaration */:
                case 222 /* InterfaceDeclaration */:
                case 220 /* FunctionDeclaration */:
                    cancellationToken.throwIfCancellationRequested();
            }
        }
        function getEncodedSemanticClassifications(fileName, span) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var typeChecker = program.getTypeChecker();
            var result = [];
            var classifiableNames = program.getClassifiableNames();
            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 === 225 /* 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(kind);
                    if (kind === 69 /* 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[identifier.text]) {
                            var symbol = typeChecker.getSymbolAtLocation(node);
                            if (symbol) {
                                var type = classifySymbol(symbol, getMeaningFromLocation(node));
                                if (type) {
                                    pushClassification(node.getStart(), node.getWidth(), type);
                                }
                            }
                        }
                    }
                    ts.forEachChild(node, processNode);
                }
            }
        }
        function getClassificationTypeName(type) {
            switch (type) {
                case 1 /* comment */: return ClassificationTypeNames.comment;
                case 2 /* identifier */: return ClassificationTypeNames.identifier;
                case 3 /* keyword */: return ClassificationTypeNames.keyword;
                case 4 /* numericLiteral */: return ClassificationTypeNames.numericLiteral;
                case 5 /* operator */: return ClassificationTypeNames.operator;
                case 6 /* stringLiteral */: return ClassificationTypeNames.stringLiteral;
                case 8 /* whiteSpace */: return ClassificationTypeNames.whiteSpace;
                case 9 /* text */: return ClassificationTypeNames.text;
                case 10 /* punctuation */: return ClassificationTypeNames.punctuation;
                case 11 /* className */: return ClassificationTypeNames.className;
                case 12 /* enumName */: return ClassificationTypeNames.enumName;
                case 13 /* interfaceName */: return ClassificationTypeNames.interfaceName;
                case 14 /* moduleName */: return ClassificationTypeNames.moduleName;
                case 15 /* typeParameterName */: return ClassificationTypeNames.typeParameterName;
                case 16 /* typeAliasName */: return ClassificationTypeNames.typeAliasName;
                case 17 /* parameterName */: return ClassificationTypeNames.parameterName;
                case 18 /* docCommentTagName */: return ClassificationTypeNames.docCommentTagName;
                case 19 /* jsxOpenTagName */: return ClassificationTypeNames.jsxOpenTagName;
                case 20 /* jsxCloseTagName */: return ClassificationTypeNames.jsxCloseTagName;
                case 21 /* jsxSelfClosingTagName */: return ClassificationTypeNames.jsxSelfClosingTagName;
                case 22 /* jsxAttribute */: return ClassificationTypeNames.jsxAttribute;
                case 23 /* jsxText */: return ClassificationTypeNames.jsxText;
                case 24 /* jsxAttributeStringLiteralValue */: return ClassificationTypeNames.jsxAttributeStringLiteralValue;
            }
        }
        function convertClassifications(classifications) {
            ts.Debug.assert(classifications.spans.length % 3 === 0);
            var dense = classifications.spans;
            var result = [];
            for (var i = 0, n = dense.length; i < n; i += 3) {
                result.push({
                    textSpan: ts.createTextSpan(dense[i], dense[i + 1]),
                    classificationType: getClassificationTypeName(dense[i + 2])
                });
            }
            return result;
        }
        function getSyntacticClassifications(fileName, span) {
            return convertClassifications(getEncodedSyntacticClassifications(fileName, span));
        }
        function getEncodedSyntacticClassifications(fileName, span) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var spanStart = span.start;
            var spanLength = span.length;
            // Make a scanner we can get trivia from.
            var triviaScanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text);
            var mergeConflictScanner = ts.createScanner(2 /* 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 ======== 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 === 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.jsDocComment) {
                        docCommentAndDiagnostics.jsDocComment.parent = token;
                        classifyJSDocComment(docCommentAndDiagnostics.jsDocComment);
                        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;
                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 */);
                    pos = tag.tagName.end;
                    switch (tag.kind) {
                        case 275 /* JSDocParameterTag */:
                            processJSDocParameterTag(tag);
                            break;
                        case 278 /* JSDocTemplateTag */:
                            processJSDocTemplateTag(tag);
                            break;
                        case 277 /* JSDocTypeTag */:
                            processElement(tag.typeExpression);
                            break;
                        case 276 /* JSDocReturnTag */:
                            processElement(tag.typeExpression);
                            break;
                    }
                    pos = tag.end;
                }
                if (pos !== docComment.end) {
                    pushCommentRange(pos, docComment.end - pos);
                }
                return;
                function processJSDocParameterTag(tag) {
                    if (tag.preParameterName) {
                        pushCommentRange(pos, tag.preParameterName.pos - pos);
                        pushClassification(tag.preParameterName.pos, tag.preParameterName.end - tag.preParameterName.pos, 17 /* parameterName */);
                        pos = tag.preParameterName.end;
                    }
                    if (tag.typeExpression) {
                        pushCommentRange(pos, tag.typeExpression.pos - pos);
                        processElement(tag.typeExpression);
                        pos = tag.typeExpression.end;
                    }
                    if (tag.postParameterName) {
                        pushCommentRange(pos, tag.postParameterName.pos - pos);
                        pushClassification(tag.postParameterName.pos, tag.postParameterName.end - tag.postParameterName.pos, 17 /* parameterName */);
                        pos = tag.postParameterName.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 ======= 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.nodeIsMissing(node)) {
                    return true;
                }
                var classifiedElementName = tryClassifyJsxElementName(node);
                if (!ts.isToken(node) && node.kind !== 244 /* JsxText */ && classifiedElementName === undefined) {
                    return false;
                }
                var tokenStart = node.kind === 244 /* 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 243 /* JsxOpeningElement */:
                        if (token.parent.tagName === token) {
                            return 19 /* jsxOpenTagName */;
                        }
                        break;
                    case 245 /* JsxClosingElement */:
                        if (token.parent.tagName === token) {
                            return 20 /* jsxCloseTagName */;
                        }
                        break;
                    case 242 /* JsxSelfClosingElement */:
                        if (token.parent.tagName === token) {
                            return 21 /* jsxSelfClosingTagName */;
                        }
                        break;
                    case 246 /* 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 === 25 /* LessThanToken */ || tokenKind === 27 /* 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 === 56 /* EqualsToken */) {
                            // the '=' in a variable declaration is special cased here.
                            if (token.parent.kind === 218 /* VariableDeclaration */ ||
                                token.parent.kind === 145 /* PropertyDeclaration */ ||
                                token.parent.kind === 142 /* Parameter */ ||
                                token.parent.kind === 246 /* JsxAttribute */) {
                                return 5 /* operator */;
                            }
                        }
                        if (token.parent.kind === 187 /* BinaryExpression */ ||
                            token.parent.kind === 185 /* PrefixUnaryExpression */ ||
                            token.parent.kind === 186 /* PostfixUnaryExpression */ ||
                            token.parent.kind === 188 /* ConditionalExpression */) {
                            return 5 /* operator */;
                        }
                    }
                    return 10 /* punctuation */;
                }
                else if (tokenKind === 8 /* NumericLiteral */) {
                    return 4 /* numericLiteral */;
                }
                else if (tokenKind === 9 /* StringLiteral */ || tokenKind === 166 /* StringLiteralType */) {
                    return token.parent.kind === 246 /* JsxAttribute */ ? 24 /* jsxAttributeStringLiteralValue */ : 6 /* stringLiteral */;
                }
                else if (tokenKind === 10 /* 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 === 244 /* JsxText */) {
                    return 23 /* jsxText */;
                }
                else if (tokenKind === 69 /* Identifier */) {
                    if (token) {
                        switch (token.parent.kind) {
                            case 221 /* ClassDeclaration */:
                                if (token.parent.name === token) {
                                    return 11 /* className */;
                                }
                                return;
                            case 141 /* TypeParameter */:
                                if (token.parent.name === token) {
                                    return 15 /* typeParameterName */;
                                }
                                return;
                            case 222 /* InterfaceDeclaration */:
                                if (token.parent.name === token) {
                                    return 13 /* interfaceName */;
                                }
                                return;
                            case 224 /* EnumDeclaration */:
                                if (token.parent.name === token) {
                                    return 12 /* enumName */;
                                }
                                return;
                            case 225 /* ModuleDeclaration */:
                                if (token.parent.name === token) {
                                    return 14 /* moduleName */;
                                }
                                return;
                            case 142 /* Parameter */:
                                if (token.parent.name === token) {
                                    var isThis_1 = token.kind === 69 /* Identifier */ && token.originalKeywordKind === 97 /* ThisKeyword */;
                                    return isThis_1 ? 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(element.kind);
                    var children = element.getChildren(sourceFile);
                    for (var i = 0, n = children.length; i < n; i++) {
                        var child = children[i];
                        if (!tryClassifyNode(child)) {
                            // Recurse into our child nodes.
                            processElement(child);
                        }
                    }
                }
            }
        }
        function getOutliningSpans(fileName) {
            // doesn't use compiler - no need to synchronize with host
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.OutliningElementsCollector.collectElements(sourceFile);
        }
        function getBraceMatchingAtPosition(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            var result = [];
            var token = ts.getTouchingToken(sourceFile, position);
            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 15 /* OpenBraceToken */: return 16 /* CloseBraceToken */;
                    case 17 /* OpenParenToken */: return 18 /* CloseParenToken */;
                    case 19 /* OpenBracketToken */: return 20 /* CloseBracketToken */;
                    case 25 /* LessThanToken */: return 27 /* GreaterThanToken */;
                    case 16 /* CloseBraceToken */: return 15 /* OpenBraceToken */;
                    case 18 /* CloseParenToken */: return 17 /* OpenParenToken */;
                    case 20 /* CloseBracketToken */: return 19 /* OpenBracketToken */;
                    case 27 /* GreaterThanToken */: return 25 /* LessThanToken */;
                }
                return undefined;
            }
        }
        function getIndentationAtPosition(fileName, position, editorOptions) {
            var start = new Date().getTime();
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start));
            start = new Date().getTime();
            var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions);
            log("getIndentationAtPosition: computeIndentation  : " + (new Date().getTime() - start));
            return result;
        }
        function getFormattingEditsForRange(fileName, start, end, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options);
        }
        function getFormattingEditsForDocument(fileName, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            return ts.formatting.formatDocument(sourceFile, getRuleProvider(options), options);
        }
        function getFormattingEditsAfterKeystroke(fileName, position, key, options) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            if (key === "}") {
                return ts.formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options);
            }
            else if (key === ";") {
                return ts.formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(options), options);
            }
            else if (key === "\n") {
                return ts.formatting.formatOnEnter(position, sourceFile, getRuleProvider(options), options);
            }
            return [];
        }
        /**
         * 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(fileName, position) {
            var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
            // 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);
            var tokenStart = tokenAtPos.getStart();
            if (!tokenAtPos || tokenStart < position) {
                return undefined;
            }
            // TODO: add support for:
            // - enums/enum members
            // - interfaces
            // - property declarations
            // - potentially property assignments
            var commentOwner;
            findOwner: for (commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
                switch (commentOwner.kind) {
                    case 220 /* FunctionDeclaration */:
                    case 147 /* MethodDeclaration */:
                    case 148 /* Constructor */:
                    case 221 /* ClassDeclaration */:
                    case 200 /* VariableStatement */:
                        break findOwner;
                    case 256 /* SourceFile */:
                        return undefined;
                    case 225 /* 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 { }'.
                        if (commentOwner.parent.kind === 225 /* ModuleDeclaration */) {
                            return undefined;
                        }
                        break findOwner;
                }
            }
            if (!commentOwner || commentOwner.getStart() < position) {
                return undefined;
            }
            var parameters = getParametersForJsDocOwningNode(commentOwner);
            var posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
            var lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
            var indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character);
            var newLine = ts.getNewLineOrDefaultFromHost(host);
            var docParams = "";
            for (var i = 0, numParams = parameters.length; i < numParams; i++) {
                var currentName = parameters[i].name;
                var paramName = currentName.kind === 69 /* Identifier */ ?
                    currentName.text :
                    "param" + i;
                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 };
        }
        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) || ts.isInComment(sourceFile, position)) {
                return false;
            }
            if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) {
                return openingBrace === 123 /* openBrace */;
            }
            if (ts.isInTemplateString(sourceFile, position)) {
                return false;
            }
            return true;
        }
        function getParametersForJsDocOwningNode(commentOwner) {
            if (ts.isFunctionLike(commentOwner)) {
                return commentOwner.parameters;
            }
            if (commentOwner.kind === 200 /* VariableStatement */) {
                var varStatement = commentOwner;
                var varDeclarations = varStatement.declarationList.declarations;
                if (varDeclarations.length === 1 && varDeclarations[0].initializer) {
                    return getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer);
                }
            }
            return emptyArray;
        }
        /**
         * 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 === 178 /* ParenthesizedExpression */) {
                rightHandSide = rightHandSide.expression;
            }
            switch (rightHandSide.kind) {
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    return rightHandSide.parameters;
                case 192 /* ClassExpression */:
                    for (var _i = 0, _a = rightHandSide.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        if (member.kind === 148 /* Constructor */) {
                            return member.parameters;
                        }
                    }
                    break;
            }
            return emptyArray;
        }
        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 = [];
            if (descriptors.length > 0) {
                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.
                    var token = ts.getTokenAtPosition(sourceFile, matchPosition);
                    if (!isInsideComment(sourceFile, token, matchPosition)) {
                        continue;
                    }
                    var descriptor = undefined;
                    for (var i = 0, n = descriptors.length; i < n; 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 getStringLiteralTypeForNode(node, typeChecker) {
            var searchNode = node.parent.kind === 166 /* StringLiteralType */ ? node.parent : node;
            var type = typeChecker.getTypeAtLocation(searchNode);
            if (type && type.flags & 256 /* StringLiteral */) {
                return type;
            }
            return undefined;
        }
        function getRenameInfo(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            var typeChecker = program.getTypeChecker();
            var defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings());
            var canonicalDefaultLibName = getCanonicalFileName(ts.normalizePath(defaultLibFileName));
            var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
            if (node) {
                if (node.kind === 69 /* Identifier */ ||
                    node.kind === 9 /* StringLiteral */ ||
                    isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
                    isThis(node)) {
                    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.forEach(declarations, isDefinedInLibraryFile)) {
                                return getRenameInfoError(ts.getLocaleSpecificMessage(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
                            }
                            var displayName = ts.stripQuotes(ts.getDeclaredName(typeChecker, symbol, node));
                            var kind = getSymbolKind(symbol, node);
                            if (kind) {
                                return {
                                    canRename: true,
                                    kind: kind,
                                    displayName: displayName,
                                    localizedErrorMessage: undefined,
                                    fullDisplayName: typeChecker.getFullyQualifiedName(symbol),
                                    kindModifiers: getSymbolModifiers(symbol),
                                    triggerSpan: createTriggerSpanForNode(node, sourceFile)
                                };
                            }
                        }
                    }
                    else if (node.kind === 9 /* StringLiteral */) {
                        var type = getStringLiteralTypeForNode(node, typeChecker);
                        if (type) {
                            if (isDefinedInLibraryFile(node)) {
                                return getRenameInfoError(ts.getLocaleSpecificMessage(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library));
                            }
                            else {
                                var displayName = ts.stripQuotes(type.text);
                                return {
                                    canRename: true,
                                    kind: ScriptElementKind.variableElement,
                                    displayName: displayName,
                                    localizedErrorMessage: undefined,
                                    fullDisplayName: displayName,
                                    kindModifiers: ScriptElementKindModifier.none,
                                    triggerSpan: createTriggerSpanForNode(node, sourceFile)
                                };
                            }
                        }
                    }
                }
            }
            return getRenameInfoError(ts.getLocaleSpecificMessage(ts.Diagnostics.You_cannot_rename_this_element));
            function getRenameInfoError(localizedErrorMessage) {
                return {
                    canRename: false,
                    localizedErrorMessage: localizedErrorMessage,
                    displayName: undefined,
                    fullDisplayName: undefined,
                    kind: undefined,
                    kindModifiers: undefined,
                    triggerSpan: undefined
                };
            }
            function isDefinedInLibraryFile(declaration) {
                if (defaultLibFileName) {
                    var sourceFile_2 = declaration.getSourceFile();
                    var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile_2.fileName));
                    if (canonicalName === canonicalDefaultLibName) {
                        return true;
                    }
                }
                return false;
            }
            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);
            }
        }
        return {
            dispose: dispose,
            cleanupSemanticCache: cleanupSemanticCache,
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
            getSyntacticClassifications: getSyntacticClassifications,
            getSemanticClassifications: getSemanticClassifications,
            getEncodedSyntacticClassifications: getEncodedSyntacticClassifications,
            getEncodedSemanticClassifications: getEncodedSemanticClassifications,
            getCompletionsAtPosition: getCompletionsAtPosition,
            getCompletionEntryDetails: getCompletionEntryDetails,
            getSignatureHelpItems: getSignatureHelpItems,
            getQuickInfoAtPosition: getQuickInfoAtPosition,
            getDefinitionAtPosition: getDefinitionAtPosition,
            getTypeDefinitionAtPosition: getTypeDefinitionAtPosition,
            getReferencesAtPosition: getReferencesAtPosition,
            findReferences: findReferences,
            getOccurrencesAtPosition: getOccurrencesAtPosition,
            getDocumentHighlights: getDocumentHighlights,
            getNameOrDottedNameSpan: getNameOrDottedNameSpan,
            getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
            getNavigateToItems: getNavigateToItems,
            getRenameInfo: getRenameInfo,
            findRenameLocations: findRenameLocations,
            getNavigationBarItems: getNavigationBarItems,
            getOutliningSpans: getOutliningSpans,
            getTodoComments: getTodoComments,
            getBraceMatchingAtPosition: getBraceMatchingAtPosition,
            getIndentationAtPosition: getIndentationAtPosition,
            getFormattingEditsForRange: getFormattingEditsForRange,
            getFormattingEditsForDocument: getFormattingEditsForDocument,
            getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
            getDocCommentTemplateAtPosition: getDocCommentTemplateAtPosition,
            isValidBraceCompletionAtPosition: isValidBraceCompletionAtPosition,
            getEmitOutput: getEmitOutput,
            getNonBoundSourceFile: getNonBoundSourceFile,
            getProgram: getProgram
        };
    }
    ts.createLanguageService = createLanguageService;
    /* @internal */
    function getNameTable(sourceFile) {
        if (!sourceFile.nameTable) {
            initializeNameTable(sourceFile);
        }
        return sourceFile.nameTable;
    }
    ts.getNameTable = getNameTable;
    function initializeNameTable(sourceFile) {
        var nameTable = {};
        walk(sourceFile);
        sourceFile.nameTable = nameTable;
        function walk(node) {
            switch (node.kind) {
                case 69 /* Identifier */:
                    nameTable[node.text] = nameTable[node.text] === undefined ? node.pos : -1;
                    break;
                case 9 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                    // 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.
                    if (ts.isDeclarationName(node) ||
                        node.parent.kind === 240 /* ExternalModuleReference */ ||
                        isArgumentOfElementAccessExpression(node) ||
                        ts.isLiteralComputedPropertyDeclarationName(node)) {
                        nameTable[node.text] = nameTable[node.text] === undefined ? node.pos : -1;
                    }
                    break;
                default:
                    ts.forEachChild(node, walk);
                    if (node.jsDocComments) {
                        for (var _i = 0, _a = node.jsDocComments; _i < _a.length; _i++) {
                            var jsDocComment = _a[_i];
                            ts.forEachChild(jsDocComment, walk);
                        }
                    }
            }
        }
    }
    function isArgumentOfElementAccessExpression(node) {
        return node &&
            node.parent &&
            node.parent.kind === 173 /* ElementAccessExpression */ &&
            node.parent.argumentExpression === node;
    }
    /// Classifier
    function createClassifier() {
        var scanner = ts.createScanner(2 /* 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[69 /* Identifier */] = true;
        noRegexTable[9 /* StringLiteral */] = true;
        noRegexTable[8 /* NumericLiteral */] = true;
        noRegexTable[10 /* RegularExpressionLiteral */] = true;
        noRegexTable[97 /* ThisKeyword */] = true;
        noRegexTable[41 /* PlusPlusToken */] = true;
        noRegexTable[42 /* MinusMinusToken */] = true;
        noRegexTable[18 /* CloseParenToken */] = true;
        noRegexTable[20 /* CloseBracketToken */] = true;
        noRegexTable[16 /* CloseBraceToken */] = true;
        noRegexTable[99 /* TrueKeyword */] = true;
        noRegexTable[84 /* 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 === 123 /* GetKeyword */ ||
                    keyword2 === 131 /* SetKeyword */ ||
                    keyword2 === 121 /* ConstructorKeyword */ ||
                    keyword2 === 113 /* 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, n = dense.length; i < n; i += 3) {
                var start = dense[i];
                var length_3 = 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: TokenClass.Whitespace });
                    }
                }
                entries.push({ length: length_3, classification: convertClassification(type) });
                lastEnd = start + length_3;
            }
            var whitespaceLength = text.length - lastEnd;
            if (whitespaceLength > 0) {
                entries.push({ length: whitespaceLength, classification: TokenClass.Whitespace });
            }
            return { entries: entries, finalLexState: classifications.endOfLineState };
        }
        function convertClassification(type) {
            switch (type) {
                case 1 /* comment */: return TokenClass.Comment;
                case 3 /* keyword */: return TokenClass.Keyword;
                case 4 /* numericLiteral */: return TokenClass.NumberLiteral;
                case 5 /* operator */: return TokenClass.Operator;
                case 6 /* stringLiteral */: return TokenClass.StringLiteral;
                case 8 /* whiteSpace */: return TokenClass.Whitespace;
                case 10 /* punctuation */: return 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 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;
                // fallthrough
                case 6 /* InTemplateSubstitutionPosition */:
                    templateStack.push(12 /* 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 === 39 /* SlashToken */ || token === 61 /* SlashEqualsToken */) && !noRegexTable[lastNonTriviaToken]) {
                        if (scanner.reScanSlashToken() === 10 /* RegularExpressionLiteral */) {
                            token = 10 /* RegularExpressionLiteral */;
                        }
                    }
                    else if (lastNonTriviaToken === 21 /* DotToken */ && isKeyword(token)) {
                        token = 69 /* 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 = 69 /* Identifier */;
                    }
                    else if (lastNonTriviaToken === 69 /* Identifier */ &&
                        token === 25 /* 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 === 27 /* GreaterThanToken */ && angleBracketStack > 0) {
                        // If we think we're currently in something generic, then mark that that
                        // generic entity is complete.
                        angleBracketStack--;
                    }
                    else if (token === 117 /* AnyKeyword */ ||
                        token === 132 /* StringKeyword */ ||
                        token === 130 /* NumberKeyword */ ||
                        token === 120 /* BooleanKeyword */ ||
                        token === 133 /* 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 = 69 /* Identifier */;
                        }
                    }
                    else if (token === 12 /* TemplateHead */) {
                        templateStack.push(token);
                    }
                    else if (token === 15 /* 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 === 16 /* 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 === 12 /* TemplateHead */) {
                                token = scanner.reScanTemplateToken();
                                // Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us.
                                if (token === 14 /* TemplateTail */) {
                                    templateStack.pop();
                                }
                                else {
                                    ts.Debug.assert(token === 13 /* TemplateMiddle */, "Should have been a template middle. Was " + token);
                                }
                            }
                            else {
                                ts.Debug.assert(lastTemplateStackToken === 15 /* OpenBraceToken */, "Should have been an open brace. Was: " + token);
                                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 */ || token === 166 /* StringLiteralType */) {
                        // 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 === 14 /* TemplateTail */) {
                                result.endOfLineState = 5 /* InTemplateMiddleOrTail */;
                            }
                            else if (token === 11 /* 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) === 12 /* 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 37 /* AsteriskToken */:
                case 39 /* SlashToken */:
                case 40 /* PercentToken */:
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                case 43 /* LessThanLessThanToken */:
                case 44 /* GreaterThanGreaterThanToken */:
                case 45 /* GreaterThanGreaterThanGreaterThanToken */:
                case 25 /* LessThanToken */:
                case 27 /* GreaterThanToken */:
                case 28 /* LessThanEqualsToken */:
                case 29 /* GreaterThanEqualsToken */:
                case 91 /* InstanceOfKeyword */:
                case 90 /* InKeyword */:
                case 116 /* AsKeyword */:
                case 30 /* EqualsEqualsToken */:
                case 31 /* ExclamationEqualsToken */:
                case 32 /* EqualsEqualsEqualsToken */:
                case 33 /* ExclamationEqualsEqualsToken */:
                case 46 /* AmpersandToken */:
                case 48 /* CaretToken */:
                case 47 /* BarToken */:
                case 51 /* AmpersandAmpersandToken */:
                case 52 /* BarBarToken */:
                case 67 /* BarEqualsToken */:
                case 66 /* AmpersandEqualsToken */:
                case 68 /* CaretEqualsToken */:
                case 63 /* LessThanLessThanEqualsToken */:
                case 64 /* GreaterThanGreaterThanEqualsToken */:
                case 65 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 57 /* PlusEqualsToken */:
                case 58 /* MinusEqualsToken */:
                case 59 /* AsteriskEqualsToken */:
                case 61 /* SlashEqualsToken */:
                case 62 /* PercentEqualsToken */:
                case 56 /* EqualsToken */:
                case 24 /* CommaToken */:
                    return true;
                default:
                    return false;
            }
        }
        function isPrefixUnaryExpressionOperatorToken(token) {
            switch (token) {
                case 35 /* PlusToken */:
                case 36 /* MinusToken */:
                case 50 /* TildeToken */:
                case 49 /* ExclamationToken */:
                case 41 /* PlusPlusToken */:
                case 42 /* MinusMinusToken */:
                    return true;
                default:
                    return false;
            }
        }
        function isKeyword(token) {
            return token >= 70 /* FirstKeyword */ && token <= 138 /* LastKeyword */;
        }
        function classFromKind(token) {
            if (isKeyword(token)) {
                return 3 /* keyword */;
            }
            else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
                return 5 /* operator */;
            }
            else if (token >= 15 /* FirstPunctuation */ && token <= 68 /* LastPunctuation */) {
                return 10 /* punctuation */;
            }
            switch (token) {
                case 8 /* NumericLiteral */:
                    return 4 /* numericLiteral */;
                case 9 /* StringLiteral */:
                case 166 /* StringLiteralType */:
                    return 6 /* stringLiteral */;
                case 10 /* 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 69 /* Identifier */:
                default:
                    if (ts.isTemplateLiteralKind(token)) {
                        return 6 /* stringLiteral */;
                    }
                    return 2 /* identifier */;
            }
        }
        return {
            getClassificationsForLine: getClassificationsForLine,
            getEncodedLexicalClassifications: getEncodedLexicalClassifications
        };
    }
    ts.createClassifier = createClassifier;
    /**
      * 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;
    function initializeServices() {
        ts.objectAllocator = {
            getNodeConstructor: function () { return NodeObject; },
            getSourceFileConstructor: function () { return SourceFileObject; },
            getSymbolConstructor: function () { return SymbolObject; },
            getTypeConstructor: function () { return TypeObject; },
            getSignatureConstructor: function () { return SignatureObject; }
        };
    }
    initializeServices();
})(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);
            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 200 /* VariableStatement */:
                            // Span on first variable declaration
                            return spanInVariableDeclaration(node.declarationList.declarations[0]);
                        case 218 /* VariableDeclaration */:
                        case 145 /* PropertyDeclaration */:
                        case 144 /* PropertySignature */:
                            return spanInVariableDeclaration(node);
                        case 142 /* Parameter */:
                            return spanInParameterDeclaration(node);
                        case 220 /* FunctionDeclaration */:
                        case 147 /* MethodDeclaration */:
                        case 146 /* MethodSignature */:
                        case 149 /* GetAccessor */:
                        case 150 /* SetAccessor */:
                        case 148 /* Constructor */:
                        case 179 /* FunctionExpression */:
                        case 180 /* ArrowFunction */:
                            return spanInFunctionDeclaration(node);
                        case 199 /* Block */:
                            if (ts.isFunctionBlock(node)) {
                                return spanInFunctionBlock(node);
                            }
                        // Fall through
                        case 226 /* ModuleBlock */:
                            return spanInBlock(node);
                        case 252 /* CatchClause */:
                            return spanInBlock(node.block);
                        case 202 /* ExpressionStatement */:
                            // span on the expression
                            return textSpan(node.expression);
                        case 211 /* ReturnStatement */:
                            // span on return keyword and expression if present
                            return textSpan(node.getChildAt(0), node.expression);
                        case 205 /* WhileStatement */:
                            // Span on while(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 204 /* DoStatement */:
                            // span in statement of the do statement
                            return spanInNode(node.statement);
                        case 217 /* DebuggerStatement */:
                            // span on debugger keyword
                            return textSpan(node.getChildAt(0));
                        case 203 /* IfStatement */:
                            // set on if(..) span
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 214 /* LabeledStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 210 /* BreakStatement */:
                        case 209 /* ContinueStatement */:
                            // On break or continue keyword and label if present
                            return textSpan(node.getChildAt(0), node.label);
                        case 206 /* ForStatement */:
                            return spanInForStatement(node);
                        case 207 /* ForInStatement */:
                            // span of for (a in ...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 208 /* ForOfStatement */:
                            // span in initializer
                            return spanInInitializerOfForLike(node);
                        case 213 /* SwitchStatement */:
                            // span on switch(...)
                            return textSpanEndingAtNextToken(node, node.expression);
                        case 249 /* CaseClause */:
                        case 250 /* DefaultClause */:
                            // span in first statement of the clause
                            return spanInNode(node.statements[0]);
                        case 216 /* TryStatement */:
                            // span in try block
                            return spanInBlock(node.tryBlock);
                        case 215 /* ThrowStatement */:
                            // span in throw ...
                            return textSpan(node, node.expression);
                        case 235 /* ExportAssignment */:
                            // span on export = id
                            return textSpan(node, node.expression);
                        case 229 /* ImportEqualsDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleReference);
                        case 230 /* ImportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 236 /* ExportDeclaration */:
                            // import statement without including semicolon
                            return textSpan(node, node.moduleSpecifier);
                        case 225 /* ModuleDeclaration */:
                            // span on complete module if it is instantiated
                            if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        case 221 /* ClassDeclaration */:
                        case 224 /* EnumDeclaration */:
                        case 255 /* EnumMember */:
                        case 169 /* BindingElement */:
                            // span on complete node
                            return textSpan(node);
                        case 212 /* WithStatement */:
                            // span in statement
                            return spanInNode(node.statement);
                        case 143 /* Decorator */:
                            return spanInNodeArray(node.parent.decorators);
                        case 167 /* ObjectBindingPattern */:
                        case 168 /* ArrayBindingPattern */:
                            return spanInBindingPattern(node);
                        // No breakpoint in interface, type alias
                        case 222 /* InterfaceDeclaration */:
                        case 223 /* TypeAliasDeclaration */:
                            return undefined;
                        // Tokens:
                        case 23 /* SemicolonToken */:
                        case 1 /* EndOfFileToken */:
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile));
                        case 24 /* CommaToken */:
                            return spanInPreviousNode(node);
                        case 15 /* OpenBraceToken */:
                            return spanInOpenBraceToken(node);
                        case 16 /* CloseBraceToken */:
                            return spanInCloseBraceToken(node);
                        case 20 /* CloseBracketToken */:
                            return spanInCloseBracketToken(node);
                        case 17 /* OpenParenToken */:
                            return spanInOpenParenToken(node);
                        case 18 /* CloseParenToken */:
                            return spanInCloseParenToken(node);
                        case 54 /* ColonToken */:
                            return spanInColonToken(node);
                        case 27 /* GreaterThanToken */:
                        case 25 /* LessThanToken */:
                            return spanInGreaterThanOrLessThanToken(node);
                        // Keywords:
                        case 104 /* WhileKeyword */:
                            return spanInWhileKeyword(node);
                        case 80 /* ElseKeyword */:
                        case 72 /* CatchKeyword */:
                        case 85 /* FinallyKeyword */:
                            return spanInNextNode(node);
                        case 138 /* 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 === 69 /* Identifier */ ||
                                node.kind == 191 /* SpreadElementExpression */ ||
                                node.kind === 253 /* PropertyAssignment */ ||
                                node.kind === 254 /* ShorthandPropertyAssignment */) &&
                                ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
                                return textSpan(node);
                            }
                            if (node.kind === 187 /* 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 === 56 /* 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 === 24 /* CommaToken */) {
                                    return spanInNode(binaryExpression.left);
                                }
                            }
                            if (ts.isExpression(node)) {
                                switch (node.parent.kind) {
                                    case 204 /* DoStatement */:
                                        // Set span as if on while keyword
                                        return spanInPreviousNode(node);
                                    case 143 /* Decorator */:
                                        // Set breakpoint on the decorator emit
                                        return spanInNode(node.parent);
                                    case 206 /* ForStatement */:
                                    case 208 /* ForOfStatement */:
                                        return textSpan(node);
                                    case 187 /* BinaryExpression */:
                                        if (node.parent.operatorToken.kind === 24 /* CommaToken */) {
                                            // If this is a comma expression, the breakpoint is possible in this expression
                                            return textSpan(node);
                                        }
                                        break;
                                    case 180 /* 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 === 253 /* 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 === 177 /* 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 === 218 /* VariableDeclaration */ ||
                                node.parent.kind === 142 /* Parameter */)) {
                                var paramOrVarDecl = node.parent;
                                if (paramOrVarDecl.initializer === node ||
                                    paramOrVarDecl.type === node ||
                                    ts.isAssignmentOperator(node.kind)) {
                                    return spanInPreviousNode(node);
                                }
                            }
                            if (node.parent.kind === 187 /* 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) {
                    var declarations = variableDeclaration.parent.declarations;
                    if (declarations && 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 === 207 /* 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 ||
                        (variableDeclaration.flags & 1 /* Export */) ||
                        variableDeclaration.parent.parent.kind === 208 /* ForOfStatement */) {
                        return textSpanFromVariableDeclaration(variableDeclaration);
                    }
                    var declarations = variableDeclaration.parent.declarations;
                    if (declarations && 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 ||
                        !!(parameter.flags & 4 /* Public */) || !!(parameter.flags & 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 !!(functionDeclaration.flags & 1 /* Export */) ||
                        (functionDeclaration.parent.kind === 221 /* ClassDeclaration */ && functionDeclaration.kind !== 148 /* 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 225 /* ModuleDeclaration */:
                            if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        // Set on parent if on same line otherwise on first statement
                        case 205 /* WhileStatement */:
                        case 203 /* IfStatement */:
                        case 207 /* 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 206 /* ForStatement */:
                        case 208 /* 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 === 219 /* 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 !== 193 /* OmittedExpression */ ? element : undefined; });
                    if (firstBindingElement) {
                        return spanInNode(firstBindingElement);
                    }
                    // Empty binding pattern of binding element, set breakpoint on binding element
                    if (bindingPattern.parent.kind === 169 /* BindingElement */) {
                        return textSpan(bindingPattern.parent);
                    }
                    // Variable declaration is used as the span
                    return textSpanFromVariableDeclaration(bindingPattern.parent);
                }
                function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node) {
                    ts.Debug.assert(node.kind !== 168 /* ArrayBindingPattern */ && node.kind !== 167 /* ObjectBindingPattern */);
                    var elements = node.kind === 170 /* ArrayLiteralExpression */ ?
                        node.elements :
                        node.properties;
                    var firstBindingElement = ts.forEach(elements, function (element) { return element.kind !== 193 /* 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 === 187 /* BinaryExpression */ ? node.parent : node);
                }
                // Tokens:
                function spanInOpenBraceToken(node) {
                    switch (node.parent.kind) {
                        case 224 /* EnumDeclaration */:
                            var enumDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile));
                        case 221 /* ClassDeclaration */:
                            var classDeclaration = node.parent;
                            return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
                        case 227 /* 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 226 /* ModuleBlock */:
                            // If this is not an instantiated module block, no bp span
                            if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) {
                                return undefined;
                            }
                        case 224 /* EnumDeclaration */:
                        case 221 /* ClassDeclaration */:
                            // Span on close brace token
                            return textSpan(node);
                        case 199 /* Block */:
                            if (ts.isFunctionBlock(node.parent)) {
                                // Span on close brace token
                                return textSpan(node);
                            }
                        // fall through
                        case 252 /* CatchClause */:
                            return spanInNode(ts.lastOrUndefined(node.parent.statements));
                        case 227 /* 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 167 /* 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 168 /* 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 === 204 /* DoStatement */ ||
                        node.parent.kind === 174 /* CallExpression */ ||
                        node.parent.kind === 175 /* NewExpression */) {
                        return spanInPreviousNode(node);
                    }
                    if (node.parent.kind === 178 /* 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 179 /* FunctionExpression */:
                        case 220 /* FunctionDeclaration */:
                        case 180 /* ArrowFunction */:
                        case 147 /* MethodDeclaration */:
                        case 146 /* MethodSignature */:
                        case 149 /* GetAccessor */:
                        case 150 /* SetAccessor */:
                        case 148 /* Constructor */:
                        case 205 /* WhileStatement */:
                        case 204 /* DoStatement */:
                        case 206 /* ForStatement */:
                        case 208 /* ForOfStatement */:
                        case 174 /* CallExpression */:
                        case 175 /* NewExpression */:
                        case 178 /* 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 === 253 /* PropertyAssignment */ ||
                        node.parent.kind === 142 /* Parameter */) {
                        return spanInPreviousNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInGreaterThanOrLessThanToken(node) {
                    if (node.parent.kind === 177 /* TypeAssertionExpression */) {
                        return spanInNextNode(node);
                    }
                    return spanInNode(node.parent);
                }
                function spanInWhileKeyword(node) {
                    if (node.parent.kind === 204 /* 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 === 208 /* 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 = {}));
//
// 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 = 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 = (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);
            // TODO: should this be '==='?
            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 = (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.lookUp(resolutionsInFile, name);
                        return result ? { resolvedFileName: result } : 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.lookUp(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.useCaseSensitiveFileNames = function () {
            return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
        };
        LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () {
            var settingsJson = this.shimHost.getCompilationSettings();
            // TODO: should this be '==='?
            if (settingsJson == null || settingsJson == "") {
                throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
            }
            return JSON.parse(settingsJson);
        };
        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 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));
        };
        return LanguageServiceShimHostAdapter;
    }());
    ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter;
    /** A cancellation that throttles calls to the host */
    var ThrottledCancellationToken = (function () {
        function ThrottledCancellationToken(hostCancellationToken) {
            this.hostCancellationToken = hostCancellationToken;
            // 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 = Date.now();
            var duration = Math.abs(time - this.lastCancellationCheckTime);
            if (duration > 10) {
                // Check no more than once every 10 ms.
                this.lastCancellationCheckTime = time;
                return this.hostCancellationToken.isCancellationRequested();
            }
            return false;
        };
        return ThrottledCancellationToken;
    }());
    var CoreServicesShimHostAdapter = (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) {
            // Wrap the API changes for 2.0 release. This try/catch
            // should be removed once TypeScript 2.0 has shipped.
            try {
                var pattern = ts.getFileMatcherPatterns(rootDir, extensions, 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));
            }
            catch (e) {
                var results = [];
                for (var _i = 0, extensions_2 = extensions; _i < extensions_2.length; _i++) {
                    var extension = extensions_2[_i];
                    for (var _a = 0, _b = this.readDirectoryFallback(rootDir, extension, exclude); _a < _b.length; _a++) {
                        var file = _b[_a];
                        if (!ts.contains(results, file)) {
                            results.push(file);
                        }
                    }
                }
                return results;
            }
        };
        CoreServicesShimHostAdapter.prototype.fileExists = function (fileName) {
            return this.shimHost.fileExists(fileName);
        };
        CoreServicesShimHostAdapter.prototype.readFile = function (fileName) {
            return this.shimHost.readFile(fileName);
        };
        CoreServicesShimHostAdapter.prototype.readDirectoryFallback = function (rootDir, extension, exclude) {
            return JSON.parse(this.shimHost.readDirectory(rootDir, extension, JSON.stringify(exclude)));
        };
        return CoreServicesShimHostAdapter;
    }());
    ts.CoreServicesShimHostAdapter = CoreServicesShimHostAdapter;
    function simpleForwardCall(logger, actionDescription, action, logPerformance) {
        var start;
        if (logPerformance) {
            logger.log(actionDescription);
            start = Date.now();
        }
        var result = action();
        if (logPerformance) {
            var end = Date.now();
            logger.log(actionDescription + " completed in " + (end - start) + " msec");
            if (typeof result === "string") {
                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 = (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 = (function (_super) {
        __extends(LanguageServiceShimObject, _super);
        function LanguageServiceShimObject(factory, host, languageService) {
            _super.call(this, factory);
            this.host = host;
            this.languageService = languageService;
            this.logPerformance = false;
            this.logger = this.host;
        }
        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); });
        };
        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); });
        };
        /// 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) {
            var _this = this;
            return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", '" + entryName + "')", function () { return _this.languageService.getCompletionEntryDetails(fileName, position, entryName); });
        };
        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) {
            var _this = this;
            return this.forwardJSONCall("getNavigateToItems('" + searchValue + "', " + maxResultCount + ")", function () { return _this.languageService.getNavigateToItems(searchValue, maxResultCount); });
        };
        LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) {
            var _this = this;
            return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () { return _this.languageService.getNavigationBarItems(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 = (function (_super) {
        __extends(ClassifierShimObject, _super);
        function ClassifierShimObject(factory, logger) {
            _super.call(this, factory);
            this.logger = logger;
            this.logPerformance = false;
            this.classifier = ts.createClassifier();
        }
        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 = (function (_super) {
        __extends(CoreServicesShimObject, _super);
        function CoreServicesShimObject(factory, logger, host) {
            _super.call(this, factory);
            this.logger = logger;
            this.host = host;
            this.logPerformance = false;
        }
        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);
                return {
                    resolvedFileName: result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined,
                    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.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.parseConfigFileTextToJson(fileName, text);
                if (result.error) {
                    return {
                        options: {},
                        typingOptions: {},
                        files: [],
                        raw: {},
                        errors: [realizeDiagnostic(result.error, "\r\n")]
                    };
                }
                var normalizedFileName = ts.normalizeSlashes(fileName);
                var configFile = ts.parseJsonConfigFileContent(result.config, _this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName);
                return {
                    options: configFile.options,
                    typingOptions: configFile.typingOptions,
                    files: configFile.fileNames,
                    raw: configFile.raw,
                    errors: realizeDiagnostics(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);
                return ts.JsTyping.discoverTypings(_this.host, info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName), info.packageNameToTypingLocation, info.typingOptions, info.compilerOptions);
            });
        };
        return CoreServicesShimObject;
    }(ShimBase));
    var TypeScriptServicesFactory = (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
            this._shims = [];
            this.documentRegistry = undefined;
        };
        TypeScriptServicesFactory.prototype.registerShim = function (shim) {
            this._shims.push(shim);
        };
        TypeScriptServicesFactory.prototype.unregisterShim = function (shim) {
            for (var i = 0, n = this._shims.length; i < n; 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 = {}));
/* tslint:disable:no-unused-variable */
// 'toolsVersion' gets consumed by the managed side, so it's not unused.
// TODO: it should be moved into a namespace though.
/* @internal */
var toolsVersion = "1.9";
/* tslint:enable:no-unused-variable */
